![](/img/trans.png)
[英]Javascript asynchronous handling without Promise and async/await
[英]JavaScript create promise queue without async/await
我正在嘗試創建一個所謂的“承諾隊列”。 這個想法是,只要還有要解決的承諾,我們就可以繼續向隊列中添加更多承諾。
我正在挑戰自己在不使用async/await
語法的情況下實現這個 promise 隊列,因為我想看看是否有可能在沒有這種語法的情況下有效地做到這一點。
我嘗試的方法是使用Promise.all
但傳遞一個自定義的可迭代 object,如果它們准時到來,它將不斷產生新的承諾。 問題是, Promise.all
不會懶惰地迭代可迭代對象,而是在一開始就一次性迭代所有承諾。
關於如何在沒有異步/等待語法的情況下有效地實現 promise 隊列的任何其他想法?
let createPromise = () => {
let resolve, reject;
let promise = new Promise((resolve_, reject_) => {
resolve = resolve_;
reject = reject_;
});
return [promise, resolve, reject];
}
let timeout = (ms) => {
let [promise, resolve, _reject] = createPromise();
setTimeout(resolve, ms);
return promise;
};
class PromiseQueue {
constructor() {
this._queue = new Set();
}
add(promise) {
this._queue.add(promise);
}
all() {
let self = this;
let alreadyIterated = false;
return Promise.all({
[Symbol.iterator]: function*() {
if (alreadyIterated) {
console.error("already iterated");
throw new Error("already iterated");
}
alreadyIterated = true;
while (true) {
let { value: promise, done } = self._queue.values().next();
if (done) {
return;
}
self._queue.delete(promise);
console.log("deleting");
yield promise;
}
}
});
}
}
let queue = new PromiseQueue();
queue.add(timeout(1000));
setTimeout(() => {
queue.add(timeout(1000));
queue.add(timeout(1000));
}, 500);
let result = await queue.all();
console.log(result);
你可以這樣做:
all() {
var iterator = this._queue.values();
function iterate() {
let v = iterator.next();
if (!v.done) {
return v.value.then(iterate);
}
}
return Promise.resolve(iterate());
}
這是受其他答案啟發的更新的PromiseQueue
實現。
class PromiseQueue {
constructor() {
this._queue = [];
}
add(promise) {
this._queue.push(promise);
}
all() {
return this._all([]);
}
_all(results) {
let all = Promise.all(this._queue);
this._queue = [];
return all.then((newResults) => {
results.push(...newResults);
if (this._queue.length > 0) {
return this._all(results);
}
return results;
});
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.