在 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 值有条件地产生,我不能这样做,因为 awaitasyncIterator 生成器函数。

我考虑过在上一次迭代中设置一个标志:

*[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
    }
}