在 asyncIterator 生成器函数中等待异步操作
Wait for an async operation inside asyncIterator generator function
我有这个 Queue
class(不是真正的实现,但它举例说明了我的观点):
class Queue {
constructor() {
this._arr = [];
}
async push(elem) {
this._arr.push(elem);
}
async pop() {
return this._arr.pop();
}
*[Symbol.asyncIterator]() {
do {
let res = await this.pop(); // here is the problem
if (res) yield res;
} while (res);
}
}
它只是 Javascript Array
的包装器,除了它的方法 return 和 Promise
.
我想做的是根据 pop()
方法的 return 值有条件地产生,我不能这样做,因为 await
在 asyncIterator
生成器函数。
我考虑过在上一次迭代中设置一个标志:
*[Symbol.asyncIterator]() {
let continue = true;
do {
yield this.pop().then(v => {
if (!v) continue = false;
return v
});
} while (continue);
}
但是在 pop()
的最后一次执行中,这仍然是 return 一个 undefined
值。
我可以在调用代码中通过检查 undefined
值作为迭代结束的信号来处理这个问题,但我想知道是否有更好的方法来解决这个问题。
您可以使用 async
generator function (MDN docs missing, but see e.g. this article) for the implementation of the [Symbol.asyncIterator]()
method:
async *[Symbol.asyncIterator]() { /*
^^^^^ */
while (this._arr.length) {
yield await this.pop(); // no longer a problem
}
}
我有这个 Queue
class(不是真正的实现,但它举例说明了我的观点):
class Queue {
constructor() {
this._arr = [];
}
async push(elem) {
this._arr.push(elem);
}
async pop() {
return this._arr.pop();
}
*[Symbol.asyncIterator]() {
do {
let res = await this.pop(); // here is the problem
if (res) yield res;
} while (res);
}
}
它只是 Javascript Array
的包装器,除了它的方法 return 和 Promise
.
我想做的是根据 pop()
方法的 return 值有条件地产生,我不能这样做,因为 await
在 asyncIterator
生成器函数。
我考虑过在上一次迭代中设置一个标志:
*[Symbol.asyncIterator]() {
let continue = true;
do {
yield this.pop().then(v => {
if (!v) continue = false;
return v
});
} while (continue);
}
但是在 pop()
的最后一次执行中,这仍然是 return 一个 undefined
值。
我可以在调用代码中通过检查 undefined
值作为迭代结束的信号来处理这个问题,但我想知道是否有更好的方法来解决这个问题。
您可以使用 async
generator function (MDN docs missing, but see e.g. this article) for the implementation of the [Symbol.asyncIterator]()
method:
async *[Symbol.asyncIterator]() { /*
^^^^^ */
while (this._arr.length) {
yield await this.pop(); // no longer a problem
}
}