Generator通过yield暂停函数执行,将异步操作结果以Promise形式返回,由执行器接收并等待其解决后,再通过next()将结果传回,实现异步流程的同步化写法。

JS协程,尤其是通过Generator实现的那种,本质上就是一种手动控制异步流程的巧妙方式,它允许我们在JavaScript中模拟出类似同步代码的执行顺序,从而极大地简化了异步操作的复杂性,尤其是在
async/await
要使用Generator实现类似
async
yield
next()
yield
我们首先定义一个Generator函数,里面用
yield
function* myAsyncFlow() {
    console.log('Step 1: 开始获取用户数据...');
    const userData = yield fetch('/api/users/1').then(res => res.json());
    console.log('Step 2: 用户数据获取成功:', userData.name);
    console.log('Step 3: 开始获取用户订单...');
    const orders = yield fetch(`/api/users/${userData.id}/orders`).then(res => res.json());
    console.log('Step 4: 用户订单获取成功:', orders.length, '个订单');
    return { userData, orders };
}然后,我们需要一个执行器来驱动这个Generator。这个执行器会不断调用Generator的
next()
next()
next()
function run(generatorFunc) {
    const generator = generatorFunc(); // 获取迭代器
    function step(nextValue) {
        const { value, done } = generator.next(nextValue); // 驱动Generator
        if (done) {
            return Promise.resolve(value); // Generator执行完毕,返回最终结果
        }
        // 如果yield出来的是一个Promise,等待它解决
        return Promise.resolve(value).then(
            res => step(res), // Promise解决,将结果传回Generator
            err => generator.throw(err) // Promise拒绝,将错误抛回Generator
        );
    }
    return step(); // 启动执行
}现在,我们就可以像这样使用它:
run(myAsyncFlow)
    .then(result => {
        console.log('所有异步操作完成,最终结果:', result);
    })
    .catch(error => {
        console.error('流程中发生错误:', error);
    });
// 模拟API
function fetch(url) {
    return new Promise(resolve => {
        setTimeout(() => {
            if (url.includes('users')) {
                resolve({
                    json: () => Promise.resolve({ id: 1, name: 'Alice' })
                });
            } else if (url.includes('orders')) {
                resolve({
                    json: () => Promise.resolve([{ id: 101, amount: 50 }, { id: 102, amount: 75 }])
                });
            }
        }, 1000);
    });
}通过这种方式,原本需要层层嵌套回调或Promise链的代码,现在可以写成看起来像同步的、自上而下的流程,这在当时(
async/await
Generator在JavaScript中模拟异步流程的暂停与恢复,其核心机制在于
yield
next()
function*
当你第一次调用这个迭代器的
next()
yield
yield
{ value: ..., done: false }value
yield
外部的执行器(就像我们上面写的
run
next()
yield
例如:
const result = yield somePromise;
当
somePromise
next()
result
async/await
async/await
构建一个简易的Generator异步执行器,通常需要以下几个核心步骤,这些步骤共同构成了一个能够驱动Generator函数,并处理其内部异步操作的完整机制。
获取Generator迭代器实例: 执行器的第一步是接收一个Generator函数,并调用它来获取一个迭代器对象。例如
const generator = generatorFunc();
定义一个递归或循环的驱动函数: 这是执行器的“心脏”。这个函数会负责不断地调用迭代器的
next()
yield
处理next()
generator.next(previousValue)
value
done
done
done
true
value
value
等待Promise解决并传递结果: 如果
value
Promise.resolve(value).then(...)
错误处理: 异步流程中错误是不可避免的。执行器需要能够捕获Promise的拒绝(rejection),并通过
generator.throw(error)
try...catch
启动执行器: 最后,需要一个初始调用来启动这个驱动函数,通常不带任何参数,因为它第一次调用
next()
yield
这些步骤形成了一个闭环,使得Generator函数能够像同步代码一样,在
yield
co
Generator实现的协程(或者说基于Generator的异步流程控制)与原生
async/await
相同点:
async/await
不同点:
底层机制:
function*
yield
yield
async/await
async
await
async
错误处理:
generator.throw(error)
try...catch
async/await
await
try...catch
灵活性与控制力:
yield
yield
async/await
await
适用场景:
async/await
Generator 实现的协程:
async/await
async/await
co
yield
总的来说,对于日常开发,
async/await
async/await
以上就是JS 协程与并发模型 - 使用 Generator 实现类似 async 的执行流程的详细内容,更多请关注php中文网其它相关文章!
 
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
 
                 
                                
                                 收藏
收藏
                                                                             
                                
                                 收藏
收藏
                                                                             
                                
                                 收藏
收藏
                                                                            Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号