如何实现send
功能,以便在保留呼叫的顺序的情况下顺序执行calculate
?
async function calculate(value) {
return new Promise((resolve) => {
setTimeout(() => resolve(value * value), 1)
})
}
async function send(value) {
return await calculate(value)
}
calculate
的下一次呼叫应在上一次呼叫结束之前开始。calculate
的呼叫应以完全相同的顺序到达。await
的当调用方忽略结果时,它应该以这种方式工作(我们总是返回结果,而不管是否使用了结果)
send(2)
send(3)
以及异步调用
;(async () => {
console.log(await send(2))
console.log(await send(3))
})()
P.S。
为什么投票不足?对于有状态的远程服务,这是一个完全合法的用例,其中calculate
将是远程调用。而且您必须保留顺序,因为远程服务是有状态的,并且结果取决于呼叫顺序。
答案 0 :(得分:1)
这是我设置异步队列的方式,以便无论如何调用,它都会按顺序处理事物:
function calculate(value) {
var reject;
var resolve;
var promise = new Promise((r, rr) => {
resolve = r;
reject = rr;
})
queue.add({
value: value,
resolve: resolve,
reject: reject
});
return promise;
}
var calcluateQueue = {
list: [], // each member of list should have a value, resolve and reject property
add: function(obj) {
this.list.push(obj); // obj should have a value, resolve and reject properties
this.processNext();
},
processNext: async function() {
if (this.processing) return; // stops you from processing two objects at once
this.processing = true;
var next = this.list.unshift(); // next is the first element on the list array
if (!next) return;
try {
var result = await doSomeProcessing(next.value);
next.resolve(result);
this.processNext();
} catch(e) {
next.reject(e);
// you can do error processing here, including conditionally putting next back onto the processing queue if you want to
// or waiting for a while until you try again
this.processNext();
}
}
};