当前位置:首页 > JavaScript

js 实现generator

2026-02-02 02:15:41JavaScript

Generator 实现基础

Generator 是 ES6 引入的一种特殊函数,通过 function* 语法定义,内部使用 yield 关键字暂停执行并返回中间值。Generator 函数调用时返回一个迭代器对象,通过调用 next() 方法逐步执行。

function* simpleGenerator() {
  yield 1;
  yield 2;
  return 3;
}

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

生成无限序列

Generator 可以用于生成无限序列,例如斐波那契数列。由于惰性求值特性,只有在调用 next() 时才会计算下一个值。

function* fibonacci() {
  let [prev, curr] = [0, 1];
  while (true) {
    yield curr;
    [prev, curr] = [curr, prev + curr];
  }
}

const fib = fibonacci();
console.log(fib.next().value); // 1
console.log(fib.next().value); // 1
console.log(fib.next().value); // 2

异步流程控制

Generator 结合 Promise 可以实现类似 async/await 的异步流程控制。通过 yield 暂停执行,等待 Promise 解析后再继续。

js 实现generator

function* asyncTask() {
  const result1 = yield fetch('https://api.example.com/data1');
  const result2 = yield fetch('https://api.example.com/data2');
  return [result1, result2];
}

function runGenerator(gen) {
  const iterator = gen();
  function handle(result) {
    if (result.done) return result.value;
    return Promise.resolve(result.value).then(res => {
      return handle(iterator.next(res));
    });
  }
  return handle(iterator.next());
}

runGenerator(asyncTask).then(results => console.log(results));

错误处理

Generator 内部可以通过 try/catch 捕获错误,外部也可以通过 iterator.throw() 方法抛出错误。

function* errorHandling() {
  try {
    yield 1;
    throw new Error('Generator error');
  } catch (e) {
    console.log('Caught inside:', e.message);
  }
}

const gen = errorHandling();
gen.next(); // { value: 1, done: false }
gen.throw(new Error('External error')); // Caught inside: External error

与迭代器协议结合

Generator 对象天然实现了迭代器协议,可以直接用于 for...of 循环或解构赋值。

js 实现generator

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

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

const [a, b] = range(1, 2);
console.log(a, b); // 1 2

yield* 委托

yield* 表达式用于委托给另一个 Generator 或可迭代对象,简化嵌套 Generator 的调用。

function* generatorA() {
  yield 'a';
  yield 'b';
}

function* generatorB() {
  yield* generatorA();
  yield 'c';
}

console.log([...generatorB()]); // ['a', 'b', 'c']

状态机应用

Generator 可以用于实现状态机,通过 yield 暂停在不同状态,通过 next() 触发状态转换。

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

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

标签: jsgenerator
分享给朋友:

相关文章

js实现动画

js实现动画

使用 CSS 动画与 JavaScript 控制 通过 JavaScript 动态添加或移除 CSS 类来触发动画。CSS 定义关键帧(@keyframes),JavaScript 通过 classL…

js实现分页

js实现分页

分页的基本实现思路 在JavaScript中实现分页功能通常需要结合前端和后端逻辑。前端负责渲染分页控件和处理用户交互,后端负责提供分页数据。 前端分页实现 纯前端分页适用于数据量较小的情况,可以…

js实现复制功能

js实现复制功能

使用 document.execCommand 方法 这种方法适用于较旧的浏览器,但在现代浏览器中可能被逐步淘汰。通过创建一个临时的 textarea 元素,将文本内容放入其中,然后执行复制命令。…

js实现图片预览

js实现图片预览

使用FileReader API实现图片预览 通过FileReader对象读取用户选择的图片文件并显示预览: const input = document.getElementById('image…

js实现复制到剪贴板

js实现复制到剪贴板

使用document.execCommand方法(传统方式,已废弃但部分浏览器仍支持) 该方法适用于旧版浏览器,但已被标记为废弃。执行前需确保文本已被选中: function copyToClip…

js实现列表

js实现列表

使用 JavaScript 实现列表 JavaScript 提供了多种方式来实现列表功能,包括数组操作、DOM 元素动态生成等。以下是几种常见的实现方法: 使用数组存储列表数据 数组是 JavaS…