You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让异步生成器无数据时暂停等待,而非直接返回undefined?

解决异步生成器等待数组新元素的问题

原代码的问题在于异步生成器没有等待逻辑,当数组当前索引无元素时直接返回undefined。要实现等待新元素推入后再返回的功能,可以通过拦截数组的push方法,配合Promise实现异步等待,且不会阻塞事件循环。

修改后的代码

async function* doIt(arr) {
    let counter = 0;
    let resolveWait;

    // 拦截数组的push方法,新元素添加时唤醒等待的生成器
    const originalPush = arr.push;
    arr.push = function(...items) {
        const result = originalPush.call(this, ...items);
        if (resolveWait) {
            resolveWait();
            resolveWait = null;
        }
        return result;
    };

    while (true) {
        // 当前索引无元素时,等待新元素被推入
        while (counter >= arr.length) {
            await new Promise(resolve => {
                resolveWait = resolve;
            });
        }
        yield arr[counter++];
    }
}

(async() => {
    let arr = [1,2,3];
    let x = doIt(arr);
    setTimeout(() => arr.push(4), 3000);
    
    console.log(await x.next()); // { value: 1, done: false }
    console.log(await x.next()); // { value: 2, done: false }
    console.log(await x.next()); // { value: 3, done: false }
    // 此处会等待3秒,直到4被推入后返回结果
    console.log(await x.next()); // { value: 4, done: false }
})()

工作原理

  1. 拦截push方法:保存数组原有的push方法,重写后在每次添加新元素时,检查是否有等待中的生成器,若有则触发resolve唤醒它。
  2. 异步等待逻辑:当生成器发现当前索引超出数组长度时,创建一个Promise并暂停执行,直到数组被push新元素时,Promise被resolve,生成器继续执行并yield新元素。
  3. 非阻塞特性:等待过程基于Promise实现,属于异步操作,不会阻塞事件循环,其他代码仍可正常运行。

内容的提问来源于stack exchange,提问作者Das Raf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 03:35:15