JS Promise 等待刷新令牌

JS Promise waitFor refresh Token

情况很简单:

我有一个使用 Bluebird 作为 Promise 处理程序的 nodejs 服务器(称为 API-A)。 我有一个客户端(浏览器)通过 API-A 请求数据,它从另一个 API (API-B) 获取数据。 API-B 可以是示例中的天气服务,然后 API-A 将数据与其他数据聚合并将其发送回客户端。

接下来的情况是:API-B需要一个TTL为1800秒的token。 因此,对于客户端发出的每个请求,我都会检查我的令牌是否已过期。

我有这样的代码:

function getActivities()
{
return this.requestAuthorisation()
       .then(()=>{
        // some other code that is not interesting
       })
}

承诺的荣耀一切正常。 requestAuthorisation() 检查令牌是否有效(下一步!!!),如果无效(我请求 API-B 刷新令牌) 问题在这里: 在令牌过期和获取新令牌的时间之间,有时会发生。如果 1000 个客户同时询问这些,我将向 API-B 请求 1000 个令牌,这并不酷。

我怎样才能避免这种情况?我尽量避免用 cron-way 来做,以避免不必要的调用,问题是一样的。

我尝试创建一种全局变量(布尔值)来跟踪令牌的刷新状态,但无法找到一种 Promise.WaitFor(变量更改) Promise.all 无法使用,因为我在不同的事件范围内。

有没有办法在令牌刷新之前排队?

请帮忙!

如果我看懂了这个写法,我们需要做两件事:

  • 不要在进行中多次调用我们的refreshToken
  • 完成后,让所有等待的请求都知道令牌请求已完成,以便他们可以继续工作。

如果您结合 Observable 模式和状态来维护进行中状态,可以像下面那样完成

// MyObservable.js:
var util = require('util');
var EventEmitter = require('events').EventEmitter;

let inProgress = false;

function MyObservable() {
  EventEmitter.call(this);
}
// This is the function responsible for getting a refresh token
MyObservable.prototype.getToken = function(token) {
  console.log('Inside getToken');
  if (!inProgress) {
    console.log('calling fetchToken');
    resultPromise = this.fetchToken();
    inProgress = true;
    resultPromise.then((result) => {
      console.log('Resolved fetch token');
      inProgress = false;
      this.emit('done', 'token refreshed');
    });
  }

}
// This is a mock function to simulate the promise based API.
MyObservable.prototype.fetchToken = function(token) {
  console.log('Inside fetchToken');
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('resolving');
      resolve("Completed");
    }, 2000);
  });
}

util.inherits(MyObservable, EventEmitter);
module.exports = MyObservable;

现在我们可以实现它并观察调用是否完成

const MyObservable = require('./MyObservable');

const observable = new MyObservable();


const A = () => {
  console.log('Inside A');
  observable.on('done', (message) => {
    console.log('Completed A');
  });
  observable.getToken('test');
}

for (let i = 0; i < 5; i++) {
  setTimeout(A, 1000);
}

如果我们 运行 这段代码,您将得到一个输出,其中 fetchToeken 仅被调用一次,即使我们的方法 A 在同一持续时间内被调用了 5 次。

希望对您有所帮助!