[英]Making an asynchronous generator *[Symbol.asyncIterator] without async/await but with promises only
現在這段代碼工作得很好
async *[Symbol.asyncIterator](){
var promise;
while (true){
promise = this.#HEAD.promise;
this.size--;
this.#HEAD.next ? this.#HEAD = this.#HEAD.next
: this.#LAST = void 0;
yield await promise;
};
};
假設我不想使用async / await
抽象,那么我如何僅通過 Promise 實現相同的功能?
我天真地嘗試過
*[Symbol.asyncIterator](){
var promise;
while (true){
promise = this.#HEAD.promise;
this.size--;
this.#HEAD.next ? this.#HEAD = this.#HEAD.next
: this.#LAST = void 0;
promise.then(yield);
};
};
但它返回undefined
; 假設yield
不是 function。 我檢查了這個問題,但它與生成器無關,也不涉及yield
。 有沒有辦法實現這個?
編輯:異步生成器中的yield await promise
似乎很浪費。 請改用yield promise
。 檢查 TJ Crowders 答案下的評論。
異步迭代器必須為結果對象(形式為{value, done}
的對象)生成 Promise。 您不能通過使用 promise 作為yield
的操作數在非async
生成器中執行此操作,因為您提供的操作數將成為結果yield
中的value
,而不是結果 ZA8CFDE6331BD59EB2AC96F8911C4B666 本身。 也就是說,當你這樣做時:
yield 42;
...在async
生成器 function 中,它為{value: 42, done: false}
生成一個 promise (使用 TypeScript 表示法, Promise<{value: 42, done: false}>
) 如果你這樣做:
yield somePromise;
...在非async
生成器 function 中,它產生{value: somePromise, done: false}
(TS: {value: Promise, done: false}
)。 這不是asyncIterator
function 定義返回的內容。 它必須為{value, done}
object 返回一個 promise,而不是無承諾的 object。
因此,如果您想避免使用async
/ await
,您至少有兩種選擇:
定義您的 object 使其不是異步可迭代的,只是可迭代的,並且它產生的值是{value: Promise, done: boolean}
。
將其定義為異步可迭代並且不要使用yield
。 顯式編寫next
方法。
對於語義,我肯定會為#2 使用 go。 如果沒有關於 object 的更多信息,很難准確顯示,但大致如下:
[Symbol.asyncIterator](){
let current = this.#HEAD;
return {
next() {
if (/*done condition*/) {
return Promise.resolve({done: true});
}
return current.promise.then(value => {
current = current.next; // or whatever
return {value, done: false};
});
}
};
}
或者,如果您希望異步迭代器 object 具有標准原型,請將其放在可以重用的地方:
const asyncIteratorPrototype =
Object.getPrototypeOf(
Object.getPrototypeOf(
(async function *(){}).prototype
)
);
然后:
[Symbol.asyncIterator](){
let current = this.#HEAD;
return Object.assign(Object.create(asyncIterator), {
next() {
if (/*done condition*/) {
return Promise.resolve({done: true});
}
return current.promise.then(value => {
current = current.next; // or whatever
return {value, done: false};
});
}
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.