【问题标题】:Wait for an async operation inside asyncIterator generator function等待 asyncIterator 生成器函数中的异步操作
【发布时间】:2021-07-04 21:48:43
【问题描述】:

我有这个Queue 类(不是真正的实现,但它体现了我的观点):

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 的包装器,除了它的方法返回一个 Promise

我想做的是根据pop() 方法的返回值有条件地产生,我不能这样做,因为await 不是asyncIterator 生成器函数内的有效操作。

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

*[Symbol.asyncIterator]() {
    let continue = true;
    do {
        yield this.pop().then(v => {
            if (!v) continue = false;
            return v
        });
    } while (continue);
}

但这仍然会在pop() 的最后一次执行中返回一个undefined 值。

我可以在调用代码中通过检查 undefined 值作为迭代结束的信号来处理这个问题,但我想知道是否有更好的方法来解决这个问题。

【问题讨论】:

  • 对于真正的队列实现,可以看看this。它还恰当地实现了[Symbol.asyncIterator](),没有任何生成器功能。

标签: javascript ecmascript-2018


【解决方案1】:

您可以使用 async generator function(缺少 MDN 文档,但请参阅例如 this article)来实现 [Symbol.asyncIterator]() method

async *[Symbol.asyncIterator]() { /*
^^^^^ */
    while (this._arr.length) {
        yield await this.pop(); // no longer a problem
    }
}

【讨论】:

  • 啊,简单。我知道这样的东西在某处存在。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-04-16
  • 1970-01-01
  • 1970-01-01
  • 2019-06-16
  • 2021-06-05
  • 2017-02-15
  • 1970-01-01
  • 2018-06-03
相关资源
最近更新 更多