Skip to main content

Generator

Generator 提供一种可分段控制任务执行的方式,通过 next 方法执行当前任务,并等待下一个任务。实际项目中,这个特性用的很少

function* getNum() {
yield 1;
yield 2;
return 3;
}
const gen = getNum();
// 需要通过 `g.next()` 的方式去执行
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);

Generator 是如何实现的呢?比如上面这段代码,通过 Babel 转译后的代码如下:

function getNum() {
return regeneratorRuntime.wrap(function getNum$(_context) {
while (1) {
switch ((_context.prev = _context.next)) {
case 0:
_context.next = 2;
return 1;

case 2:
_context.next = 4;
return 2;

case 4:
return _context.abrupt("return", 3);

case 5:
case "end":
return _context.stop();
}
}
}, _marked);
}

let gen = getNum();
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);

// wrap函数类似于下面的代码
function wrap(getNum) {
let context = new Context();
return {
next: function () {
value = getNum(context);
done = context.done;
return {
value,
done,
};
},
};
}

其实 Generator 实现的核心就在于上下文的保存,每一次执行到 yield,其实都执行了一遍传入的生成器函数(getNum$),只是在这个过程中间用了一个 context 对象储存上下文,使得每次执行生成器函数的时候,都可以从上一个执行结果开始执行