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 次。
希望对您有所帮助!
情况很简单:
我有一个使用 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 次。
希望对您有所帮助!