JavaScript yield与异步编程

什么是 yield

yield 关键字只能在生成器函数中使用。生成器函数是一种特殊的函数,使用 function* 声明。当生成器函数执行到 yield 表达式时,它会暂停执行,并将 yield 后面的值返回给调用者。重要的是,函数的状态会被保存,以便稍后可以从暂停的地方继续执行。

生成器函数的基本语法:

javascript 复制代码
function* myGenerator() {
  yield 1;
  yield 2;
  yield 3;
}

const generator = myGenerator();

console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: 3, done: false }
console.log(generator.next()); // { value: undefined, done: true }
  • function* myGenerator(): 声明一个生成器函数。
  • yield 1;: 暂停函数执行,并返回 1
  • generator.next(): 调用 next() 方法恢复函数的执行,并返回一个包含 valuedone 属性的对象。value 属性是 yield 表达式的值,done 属性表示生成器函数是否已经执行完毕。

双向通信
yield不仅能向外传递值,还能通过next(value)接收外部输入:

javascript 复制代码
function* calculator() {  
  const a = yield 'Enter a:'; 
  console.log(a)
  const b = yield 'Enter b:'; 
  console.log(b)
  return a + b;  
}  
const cal = calculator();  
cal.next();    // {value: 'Enter a:', done: false}  
cal.next(2);   // {value: 'Enter b:', done: false}  
cal.next(3);   // {value: 5, done: true}  

这种特性使得生成器可以动态响应外部逻辑

yield 的强大之处:

  1. 控制迭代过程: yield 允许你自定义迭代过程,按需生成值。这对于处理大型数据集或无限序列非常有用,可以避免一次性加载所有数据到内存中。

    javascript 复制代码
    function* infiniteSequence() {
      let i = 0;
      while (true) {
        yield i++;
      }
    }
    
    const sequence = infiniteSequence();
    
    console.log(sequence.next().value); // 0
    console.log(sequence.next().value); // 1
    console.log(sequence.next().value); // 2
    // ... 无限循环
  2. 实现状态机: yield 可以用于实现状态机,控制程序在不同状态之间的转换。

    javascript 复制代码
    function* stateMachine() {
      let state = 'start';
    
      while (true) {
        switch (state) {
          case 'start':
            console.log('Starting...');
            state = yield 'waiting';
            break;
          case 'waiting':
            console.log('Waiting for input...');
            state = yield 'processing';
            break;
          case 'processing':
            console.log('Processing data...');
            state = yield 'done';
            break;
          case 'done':
            console.log('Done!');
            return;
          default:
            console.log('Invalid state!');
            return;
        }
      }
    }
    
    const machine = stateMachine();
    console.log(machine.next()); // Starting... { value: 'waiting', done: false }
    console.log(machine.next('processing')); // Waiting for input... { value: 'processing', done: false }
    console.log(machine.next('done')); // Processing data... { value: 'done', done: false }
    console.log(machine.next()); // Done! { value: undefined, done: true }
相关推荐
顾安r2 小时前
11.8 脚本网页 星际逃生
c语言·前端·javascript·flask
Hello.Reader2 小时前
Data Sink定义、参数与可落地示例
java·前端·网络
im_AMBER3 小时前
React 17
前端·javascript·笔记·学习·react.js·前端框架
一雨方知深秋3 小时前
2.fs模块对计算机硬盘进行读写操作(Promise进行封装)
javascript·node.js·promise·v8·cpython
谷歌开发者4 小时前
Web 开发指向标 | Chrome 开发者工具学习资源 (六)
前端·chrome·学习
一晌小贪欢4 小时前
【Html模板】电商运营可视化大屏模板 Excel存储 + 一键导出(已上线-可预览)
前端·数据分析·html·excel·数据看板·电商大屏·大屏看板
发现你走远了4 小时前
连接模拟器网页进行h5的调试(使用Chrome远程调试(推荐)) 保姆级图文
前端·chrome
街尾杂货店&5 小时前
css - 实现三角形 div 容器,用css画一个三角形(提供示例源码)简单粗暴几行代码搞定!
前端·css
顺凡5 小时前
删一个却少俩:Antd Tag 多节点同时消失的原因
前端·javascript·面试
小白路过5 小时前
CSS transform矩阵变换全面解析
前端·css·矩阵