es6的Generator函数用法

news/2025/2/23 0:18:27

目录

  1. 基本概念
  2. 语法特性
  3. 使用场景
  4. 异步应用
  5. 高级用法
  6. 最佳实践

基本概念

什么是 Generator 函数?

Generator 函数是 ES6 提供的一种异步编程解决方案,它可以让函数执行过程中被暂停和恢复。Generator 函数通过 function* 声明,内部使用 yield 关键字暂停执行。

特点

  1. 函数体内部使用 yield 表达式
  2. 函数返回一个遍历器对象
  3. 可以暂停执行和恢复执行
  4. 可以记住上一次运行状态

语法特性

1. 基本语法

javascript">function* generator() {
  yield 1;
  yield 2;
  yield 3;
}

const gen = generator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }

2. yield* 表达式

javascript">function* foo() {
  yield 'a';
  yield 'b';
}

function* bar() {
  yield 'x';
  yield* foo();  // 委托给其他 Generator 函数
  yield 'y';
}

const gen = bar();
console.log([...gen]); // ['x', 'a', 'b', 'y']

3. 传值与返回值

javascript">function* dataFlow() {
  const x = yield 1;
  const y = yield (x + 1);
  return x + y;
}

const gen = dataFlow();
console.log(gen.next());     // { value: 1, done: false }
console.log(gen.next(2));    // { value: 3, done: false }
console.log(gen.next(3));    // { value: 5, done: true }

使用场景

1. 异步操作流程控制

javascript">function* loadData() {
  try {
    const users = yield fetchUsers();
    const posts = yield fetchPosts(users[0].id);
    const comments = yield fetchComments(posts[0].id);
    return { users, posts, comments };
  } catch (error) {
    console.error('Error:', error);
  }
}

// 执行器函数
function run(generator) {
  const gen = generator();
  
  function next(data) {
    const result = gen.next(data);
    if (result.done) return result.value;
    
    result.value.then(data => next(data));
  }
  
  return next();
}

run(loadData);

2. 迭代器实现

javascript">function* range(start, end) {
  for (let i = start; i <= end; i++) {
    yield i;
  }
}

const numbers = range(1, 5);
for (const num of numbers) {
  console.log(num); // 1, 2, 3, 4, 5
}

3. 状态机

javascript">function* trafficLight() {
  while (true) {
    yield 'red';
    yield 'green';
    yield 'yellow';
  }
}

const light = trafficLight();
console.log(light.next().value); // 'red'
console.log(light.next().value); // 'green'
console.log(light.next().value); // 'yellow'

异步应用

1. 异步任务队列

javascript">function* taskQueue() {
  const results = [];
  
  try {
    results.push(yield task1());
    results.push(yield task2());
    results.push(yield task3());
    return results;
  } catch (error) {
    console.error('Task failed:', error);
  }
}

2. 异步数据处理

javascript">function* processData(data) {
  for (const item of data) {
    const processed = yield transform(item);
    yield save(processed);
  }
}

高级用法

1. 双向通信

javascript">function* chat() {
  while (true) {
    const question = yield;
    if (question === 'bye') break;
    yield `Answer to: ${question}`;
  }
}

const conversation = chat();
conversation.next();           // 启动生成器
console.log(conversation.next('How are you?').value);  // "Answer to: How are you?"

2. 错误处理

javascript">function* errorHandler() {
  try {
    const a = yield operation1();
    const b = yield operation2();
    const c = yield operation3();
  } catch (error) {
    yield `Error occurred: ${error.message}`;
  }
}

最佳实践

1. 使用执行器函数

javascript">function run(gen) {
  const it = gen();
  
  return new Promise((resolve, reject) => {
    function next(data) {
      const { value, done } = it.next(data);
      if (done) return resolve(value);
      
      Promise.resolve(value)
        .then(data => next(data))
        .catch(reject);
    }
    
    next();
  });
}

2. 合理使用 yield*

javascript">function* combined() {
  yield* generator1();
  yield* generator2();
  yield* generator3();
}

总结

  1. Generator 优势:

    • 控制函数执行流程
    • 异步操作同步化表达
    • 状态管理
    • 迭代器实现
  2. 使用场景:

    • 异步操作控制
    • 数据流处理
    • 状态机实现
    • 迭代器生成
  3. 注意事项:

    • 合理使用执行器
    • 错误处理
    • 避免过度使用
    • 考虑可读性

http://www.niftyadmin.cn/n/5862865.html

相关文章

【练习】【回溯:组合:一个集合 元素可重复】力扣 39. 组合总和

题目 组合总和 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重…

网页制作05-html,css,javascript初认识のhtml表格的创建

一、创建表格 1、表格的基本构成&#xff1a; Table&#xff0c; Tr,td 1&#xff09;简介&#xff1a; 表格是由行列和单元格三部分组成的&#xff0c;一般通过三个标记来创建&#xff1a; Table&#xff0c;表格标记 Tr,行标记 td&#xff0c;单元格标记 2&#xff09…

vue和微信小程序处理markdown格式数据

【1】Vue处理markdown数据 在Vue项目中展示Markdown格式的数据&#xff0c;比如通义千问模型返回的数据&#xff0c;你可以借助一些Markdown解析库将Markdown文本转换为HTML&#xff0c;然后在页面上渲染。以下为你详细介绍几种常用的实现方式。 方法一&#xff1a;使用marke…

2025年能源会议要点

2025年全国能源工作会议于2024年12月15日在北京召开&#xff0c;这次会议是国家能源局在新的一年里对全国能源工作的规划与部署的重要会议。 会议特别强调了加快构建新型能源体系、推动能源高质量发展的重要性&#xff0c;并明确提出了2025年要初步建成全国统一电力市场的目标。…

Docket Desktop 安装redis 并设置密码

以下是在 Docker Desktop 中安装 Redis 并设置密码的详细步骤&#xff1a; 步骤 1&#xff1a;启动 Docker Desktop 确保你的 Docker Desktop 已经正确安装并且已经启动。你可以在任务栏或者系统托盘中找到 Docker 图标&#xff0c;确认其处于运行状态。 步骤 2&#xff1a;…

【QT中的一些高级数据结构,持续更新中...】

QT中有一些很精妙、便捷的设计&#xff0c;在了解这些数据的同时&#xff0c;我们可以学到如何更好的设计代码。本贴持续更新中&#xff0c;欢迎关注和收藏 一 QScopedPointer主要特点&#xff1a;示例代码 二 Q_DISABLE_COPY 一 QScopedPointer QScopedPointer 是 Qt 中的一种…

Html5学习教程,从入门到精通,HTML5 元素语法知识点及案例代码(2)

HTML5 元素语法知识点及案例代码 一、HTML5 元素概述 HTML5 元素是构成网页的基本单位&#xff0c;每个元素都有特定的语义和功能。HTML5 元素由开始标签、内容和结束标签组成&#xff0c;例如&#xff1a; <p>这是一个段落。</p><p> 是开始标签这是一个段…

Flutter - 初体验

项目文件目录结构介绍 注&#xff1a;创建 Flutter 项目名称不要包含特殊字符&#xff0c;不要使用驼峰标识 // TODO 开发中运行一个 Flutter 三种启动方式 Run 冷启动从零开始启动Hot Reload 热重载执行 build 方法Hot Restart 热重启重新运行整个 APP 先看效果&#xff0c…