创建异步迭代器的最佳实践是什么?我应该使用异步生成器函数还是使用 Symbol.asyncIterator?

ena*_*one 2 javascript iterator generator node.js async-await

此代码按预期工作:

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function getAsyncData() {
    await sleep(1000);  // simulate database/network delay...
    return [1, 2, 3, 4, 5];  // ...then return some data
}

const asyncIterable = (async function* filterAsyncData() {
    const items = await getAsyncData();

    for (const item of items) {
        yield item;
    }
})();

const asyncIterable2 = {
    [Symbol.asyncIterator]() {
        return {
            values: null,
            idx: 0,
            async next() {
                if (this.values === null) {
                    this.values = await getAsyncData();
                }

                if (this.idx < this.values.length) {
                    this.idx = this.idx + 1;
                    return Promise.resolve({ value: this.values[this.idx - 1], done: false });
                }

                return Promise.resolve({ done: true });
            }
        };
    }
};

async function main() {
    for await (const filteredItem of asyncIterable) {
        console.log(filteredItem);
    }
}

main()
Run Code Online (Sandbox Code Playgroud)

如果我在函数中使用asyncIterableor并不重要,我总是得到相同的结果。定义可迭代的最佳实践是什么?是否有任何关于首选选项的指南?为什么?asyncIterable2main

Ber*_*rgi 6

与同步迭代器相同:生成器函数比手动实现迭代器对象更容易编写,也更容易获得正确性。仅当您需要一些无法通过其他方式实现的非标准行为时才执行此操作。特别是对于异步生成器函数,您甚至可以next免费获得正确的调用排队,这是一个真正令人头痛的问题(您asyncIterable2失败了这个1)。

可迭代对象最常见的实现是使该Symbol.asyncIterator方法成为异步生成器方法:

const asyncIterable = {
    async *[Symbol.asyncIterator]() {
         yield* await getAsyncData();
    },
};
Run Code Online (Sandbox Code Playgroud)

1: -中间const it = asyncIterable2[Symbol.asyncIterator](); it.next(); it.next()没有任何s - 将调用两次,因为在两次调用中awaitgetAsyncDatathis.values == null