情况很简单:
我有一个使用Bluebird作为Promise处理程序的nodejs服务器(称为API-A)。 我有一个客户端(浏览器)通过API-A询问数据,该API从另一个API(API-B)获取数据。 API-B可以是示例中的Weather服务,然后API-A将数据与其他数据聚合并将其发送回客户端。
情况如下:API-B需要一个TTL为1800秒的令牌。 因此,对于客户端完成的每个请求,我都会检查我的令牌是否已过期。
我有这样的代码:
function getActivities()
{
return this.requestAuthorisation()
.then(()=>{
// some other code that is not interesting
})
}
一切都与诺言的荣耀一致。 requestAuthorisation()检查令牌是否有效(下一个!!!),如果没有(我请求API-B刷新令牌) 问题出在这里: 在时间,令牌过期和获得新鲜的时间之间,有时会发生。如果1000个客户同时询问这些,我将向API-B提出1000个令牌请求,这并不酷。
我该如何避免?我尽量避免使用cron方式,以避免不必要的调用,问题是一样的。
我尝试创建一种全局变量(boolean)来跟踪令牌的刷新状态但是找不到一种Promise.WaitFor(变量更改) Promise.all无法使用,因为我处于不同的事件范围内。
在令牌刷新之前有没有办法排队?
请帮忙!
答案 0 :(得分:2)
如果我理解这篇文章,我们需要做两件事:
如果将Observable模式和状态结合起来以维持正在进行的状态,可以像下面这样完成
MemTotal: 30946088 kB
MemFree: 11252496 kB
Buffers: 496376 kB
Cached: 11938144 kB
SwapCached: 0 kB
Active: 15023232 kB
Inactive: 3116316 kB
Active(anon): 5709860 kB
Inactive(anon): 394092 kB
Active(file): 9313372 kB
Inactive(file): 2722224 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 15728636 kB
SwapFree: 15728636 kB
Dirty: 280 kB
Writeback: 0 kB
AnonPages: 5705052 kB
Mapped: 461876 kB
Shmem: 398936 kB
Slab: 803936 kB
SReclaimable: 692240 kB
SUnreclaim: 111696 kB
KernelStack: 33520 kB
PageTables: 342840 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 31201680 kB
Committed_AS: 26896520 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 73516 kB
VmallocChunk: 34359538628 kB
HardwareCorrupted: 0 kB
AnonHugePages: 2887680 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 6132 kB
DirectMap2M: 2091008 kB
DirectMap1G: 29360128 kB
现在我们可以实现这个并观察完成的调用
// 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);
}
在相同的持续时间内被调用了5次,您将获得仅fetchToeken
被调用一次的输出。
希望这有帮助!