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 }
相关推荐
wangdaoyin20101 天前
若依vue2前后端分离集成flowable
开发语言·前端·javascript
天天进步20151 天前
AI Agent 与流式处理:Motia 在生成式 AI 时代的后端范式
javascript
心柠1 天前
vue3相关知识总结
前端·javascript·vue.js
Amumu121381 天前
Vue Router(二)
java·前端
a1117761 天前
图书借阅管理系统(FastAPI + Vue)
前端·vue.js·fastapi
常年游走在bug的边缘1 天前
掌握JavaScript作用域:从函数作用域到块级作用域的演进与实践
开发语言·前端·javascript
极致♀雨1 天前
vue2+elementUI table表格勾选行冻结/置顶
前端·javascript·vue.js·elementui
林shir1 天前
3-15-前端Web实战(Vue工程化+ElementPlus)
前端·javascript·vue.js
zhaoyin19941 天前
Fiddler弱网实战
前端·测试工具·fiddler
换日线°1 天前
前端炫酷展开效果
前端·javascript·vue