多次调用_dispatch
有时会导致同时传递给_dispatch
的承诺。不是.then应该在之前的.then之后执行吗?
// Failing code
async _dispatch (promise) {
// this._mutex is a Promise
this._mutex = this._mutex.then(() => promise)
return Promise.resolve(this._mutex)
}
// Possibly working code
async _dispatch (promise) {
console.log('START_CS', promise)
while (Atomics.load(this.done, 0) === 0) {
await this.sleep(50)
}
Atomics.store(this.done, 0, 0)
console.log('IN_CS', promise)
const ret = await promise
Atomics.store(this.done, 0, 1)
console.log('END_CS', promise)
return ret
}
_dispatch
的使用方式如下:
async getStatus (ports) {
const request = // ...
return this._dispatch(someAsyncFunctionReturningArray(request, ports))
}
const polling = () => {
const sleep = new Promise(resolve => setTimeout(resolve, 500))
const status = this.getStatus().then(() => {}).catch(() => {})
return Promise.all([sleep, status])
.then(polling)
}
polling()
polling()和另一个类似的代码块正在同时运行。我注意到someAsyncFunctionReturningArray
被同时调用。
答案 0 :(得分:1)
Promise携带有关任务状态的信息,并允许您对状态进行操作。通常,它们本身并不代表任务。这相当于您正在做的事情:
async function foo() {
console.log('foo() task ran');
}
function delay() {
return new Promise(resolve => {
setTimeout(resolve, 1000);
});
}
const promise = foo();
delay().then(() => promise)
这不会延迟promise
一秒钟,因为promise
只是一个可以说“用值X解析”,“被错误Y拒绝”或“待处理”的对象。 。没有延迟承诺的概念-您延迟任务。该工作由foo
完成,并在您致电foo()
时开始。
目前尚不清楚您要提出的问题是正确的替代方法。我想这就是你要去的地方
_dispatch (action) {
this._mutex = this._mutex.then(() => action())
return this._mutex
}
async getStatus (ports) {
const request = // ...
return this._dispatch(() => someAsyncFunctionReturningArray(request, ports))
}
,但是可能有一种完全不同的方法会更有效,并且我们需要更多有关您要使用此队列来完成的工作的详细信息,以推荐一个方法。
答案 1 :(得分:0)
一个Promise并不是一个生成值的任务,而是一个需要花费一段时间的任务立即返回的值,然后才将结果传递出去。通过将它们链接在一起,将一个许诺添加到另一个许诺中不会影响任务的执行。但是,当承诺解决时,可以调用回调,例如:
async _dispatch(callback) {
this._mutex = this._mutex.then(() => callback());
return this._mutex;
}
然后可以用作:
const getStatus = (ports) => this.dispatch(() => {
const request = // ...
return someAsyncFunctionReturningArray(request, ports);
});
const sleep = new Promise(resolve => setTimeout(resolve, 500))
const polling = () => {
const status = this.getStatus().then(() => {}).catch(() => {})
return Promise.all([sleep, status])
.then(polling)
};
polling();