[英]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.