2015-10-16 48 views
2

所以我有一個服務暴露給多個角度控制器。該服務檢查我們的訪問令牌是否有效,如果不是,請求服務器獲取新的訪問令牌(通過發送刷新令牌)。是否有一種設計模式可以「擺脫」許多對「相同」承諾的要求?

我希望每個控制器檢查我們的令牌是否有效,並且只在一段時間內發出單個服務器調用(如果它無效)。由於這是異步的,任何數量的控制器都可以同時調用該函數(例如,在用戶導航到新的路由之後,可以初始化5個新的控制器)。我們無法保證模型中的標記變量的有效性,因爲第一個請求可能已經在運行,而且我們不知道變量的狀態是前或後飛行(我們不能只存儲狀態並認爲它是猶太)。

我可能會「反彈」的方式是將承諾參考存儲在我的模型中,如果存在,則返回模型的承諾而不是新承諾。然後,在「去抖期」結束之前,我不會提出第一個請求。

所以,我想知道是否有更多'Q'ey的方式來做到這一點?這是一種反模式嗎?這完全合適嗎?

// in the model/service 

    var model = { 
    queuedPromise:null, 
    getCurrentUser: function(){ 

     var deferred = $q.defer(); 

     if(model.queuedPromise) 
     { 
     return model.queuedPromise; 
     } 

     // let's debounce and only call the functions after 100 ms have elapsed since the first call 
     setTimeout(function() { 
     deferred.resolve( model.checkRefreshToken().then(function() { 
      model.getUserData().then(function() { 
       model.queuedPromise = null; 
      }); 
      }) 
     ); 

     }, 100); 

     // Many controllers may call this at once async, so store the first promise reference and return that for all subsequent calls. 
     model.queuedPromise = deferred.promise; 
     return deferred.promise; 
    } 
}; 
//... 
return model; 
+0

通過只讀標題:「是的,這就是所謂的一個承諾就是太寬泛」 –

+0

我不要求有關承諾的設計模式,我想諮詢一下特定的設計模式,爲特定用例。在假設你知道內容之前,你可能想要比標題更深入地閱讀。 – FlavorScape

+0

看起來完全適合我。可能還有其他方法可以做到這一點,但是,您做這件事的方式非常簡單易用。 –

回答

0

我在原代碼中發現了一個錯誤,下面是解決方案。這裏的「模式」的關鍵是,你必須等待,直到承諾返回使其無效(對於下一頁重新加載/需要此功能的時間)。

  var deferred = $q.defer(); 
      if(model.queuedPromise) 
      { 
      return model.queuedPromise; 
      } 

      setTimeout(function() { 
      model.checkRefreshToken().then(function() { 
       model.getUserData().then(function() { 

        // only nullify after the promise handlers are invoked 
        setTimeout(function(){ 
        model.queuedPromise = null; 
        }, 1); 

        deferred.resolve({}); 

       }); 
       }); 

      }, 100); 


      model.queuedPromise = deferred.promise; 
      return model.queuedPromise; 
相關問題