"debouncing" 对 'same' 承诺的许多请求是否有设计模式?

Is there a design pattern for "debouncing" many requests to the 'same' promise?

所以我有一个服务暴露给多个 angular 控制器。此服务检查我们的访问令牌是否有效,如果无效,则向服务器发出请求以获取新的访问令牌(通过发送刷新令牌)。

我希望每个控制器检查我们的令牌是否有效,如果无效则在一段时间内只进行一次服务器调用。由于这是异步的,因此任何数量的控制器都可以同时调用此函数(例如,在用户导航到新路线后,可能会初始化 5 个新控制器)。我们不能保证模型中令牌变量的有效性,因为第一个请求可能已经在飞行中,我们不知道变量的状态是预飞行还是 post 飞行(我们不能只存储状态并认为它是犹太洁食)。

我可能 "debounce" 的方式是将 promise 引用存储在我的模型中,然后如果它存在,return 模型的 promise 而不是新的。然后在 'debounce period' 结束之前我不会提出第一个请求。

所以,我想知道是否有更“Q”的方式来做到这一点?这是反模式吗?这完全足够了吗?

  // 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;

我在原始代码中发现了一个错误,这是解决方案。这里 "pattern" 的关键是你必须等到承诺 returns 才能使它无效(下一页 reload/time 需要这个功能)。

          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;