17370845950

JavaScript协程实现_Generator异步流程控制
JavaScript中通过Generator函数实现协程,使用function定义并返回迭代器,调用next()可暂停和恢复执行,yield用于暂停并返回值,next再启动生成器。示例展示其逐步执行特性:function simpleGen() { yield '第一步'; yield '第二步'; return '完成'; } const gen = simpleGen(); console.log(gen.next()); // { value: '第一步', done: false } console.log(gen.next()); // { value: '第二步', done: false } console.log(gen.next()); // { value: '完成', done: true } 可将异步操作封装在yield后,由运行器捕获Promise并在resolve后通过next送回结果,实现同步写法处理异步逻辑。运行器递归调用next,监听Promise状态,如:function run(generatorFn) { const iterator = generatorFn(); function handle(result) { if (result.done) return Promise.resolve(result.value); return Promise.resolve(result.value).then(data => handle(iterator.next(data))).catch(err => handle(iterator.throw(err))); } try { return handle(iterator.next()); } catch (err) { return Promise.reject(err); } } 使用delay模拟异步:function delay(ms, value) { return new Promise(resolve => setTimeout(() => resolve(value), ms)); } function* asyncFlow() { const data1 = yield delay(1000, '第一次完成'); console.log(data1); const data

JavaScript中的协程通过Generator函数实现,为异步流程控制提供了更优雅的解决方案。它能让函数执行到某一步暂停,等异步操作完成后再恢复,从而以同步写法处理异步逻辑。

Generator基础:暂停与恢复执行

Generator函数是协程在JavaScript中的实现方式,定义时使用function*语法。调用后返回一个迭代器对象,可通过next()方法控制执行流程。

每次遇到yield表达式,函数会暂停,并将值返回给调用者;下一次调用next()时继续执行,直到遇到下一个yield或函数结束。

示例:
function* simpleGen() {
  yield '第一步';
  yield '第二步';
  return '完成';
}

const gen = simpleGen(); console.log(gen.next()); // { value: '第一步', done: false } console.log(gen.next()); // { value: '第二步', done: false } console.log(gen.next()); // { value: '完成', done: true }

用Generator控制异步任务

将异步操作封装在yield后,由外部运行器捕获并执行回调,完成后将结果送回Generator继续执行,形成“暂停→等待→恢复”的流程。

常见模式是让yield后跟一个Promise,运行器自动监听其完成状态。

基本思路:
  • Generator产出一个Promise
  • 运行器监听Promise的resolve/reject
  • 结果通过next(value)throw(error)送回函数体内
  • 函数继续执行,像同步代码一样处理结果

手动实现一个简单的运行器

运行器(Runner)是驱动Generator自动执行的核心。它递归调用next(),并在Promise完成时传入结果。

function run(generatorFn) {
  const iterator = generatorFn();

function handle(result) { if (result.done) return Promise.resolve(result.value);

return Promise.resolve(result.value)
  .then(data => handle(iterator.next(data)))
  .catch(err => handle(iterator.throw(err)));

}

try { return handle(iterator.next()); } catch (err) { return Promise.reject(err); } }

使用示例:

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

function* asyncFlow() { const data1 = yield delay(1000, '第一次完成'); console.log(data1);

const data2 = yield delay(500, '第二次完成'); console.log(data2);

return '全部结束'; }

run(asyncFlow); // 按顺序输出,无需嵌套回调

Generator与现代异步方案的对比

虽然Generator曾是异步编程的重要突破,但如今已被async/await取代。后者本质上是Generator + Promise的语法糖,但更简洁、易读。

优点:
  • 以同步形式书写异步逻辑,减少回调地狱
  • 支持try/catch处理异步错误
  • 可组合多个异步步骤,便于调试和维护
局限:
  • 需配合运行器使用,不够原生
  • 错误传播需手动处理
  • 语法复杂度高,不如async/await直观

基本上就这些。Generator展示了JavaScript如何通过协程思想改善异步控制流,虽然后续被更优方案替代,但理解其原理对掌握现代异步机制仍有帮助。