Koa.js 生成器 - Generators
JavaScript ES6 最令人兴奋的新特性之一是一种新的函数,称为生成器 - Generators。 在生成器之前,整个脚本通常以从上到下的顺序执行,没有简单的方法来停止代码执行并稍后使用相同的堆栈恢复。 生成器是可以退出并稍后重新进入的功能。 它们的上下文(变量绑定)将在重新进入时保存。
生成器允许我们在两者之间停止代码执行。 因此,让我们看一个简单的生成器。
var generator_func = function* (){ yield 1; yield 2; }; var itr = generator_func(); console.log(itr.next()); console.log(itr.next()); console.log(itr.next());
运行上述代码时,结果如下。
{ value: 1, done: false }
{ value: 2, done: false }
{ value: undefined, done: true }
让我们看看上面的代码。 我们首先创建一个名为 generator_func()
的生成器。 我们创建了这个看起来很奇怪的函数的实例并将其分配给 itr。 然后我们开始在这个 itr 变量上调用 next()。
调用 next() 启动生成器并运行直到它达到一个 yield
。 然后它返回具有值和完成的对象,其中值具有表达式值。 这个表达式可以是任何东西。 此时,它暂停执行。 当我们再次调用这个函数(next)时,生成器从最后一个 yield 点恢复执行,函数状态与暂停时相同,直到下一个 yield 点。 这样做直到代码中没有更多的 yield 点。
Koa 中的生成器
那么我们为什么要在本教程中讨论生成器。 您可能还记得 “hello 迹忆客!” 程序中的内容,我们使用 function* ()
表示法将回调传递给 app.use()
。 Koa 是一个对象,其中包含一组中间件生成器函数,所有这些函数都在每次请求时以类似堆栈的方式组合和执行。 Koa 还实现了控制流的下游化和上游化。
请查看以下示例来更好地理解这一点。
var koa = require('koa');
var app = new koa();
app.use(function* (next) {
// 在 yield 下一个生成器函数之前做一些事情
// 在这一行中,这将是下游的第一个事件
console.log("1");
yield next;
// 当执行返回上游时执行一些操作,
// 这将是上游的最后一个活动
console.log("2");
});
app.use(function* (next) {
// 这应该是下游的第二个事件
console.log("3");
yield next;
// 这将是上游的第二个事件
console.log("4");
});
app.use(function* () {
// 这将是下游的最后一个功能
console.log("5");
// 设置响应正文
this.body = "Hello Generators";
// 上游的第一个事件(从最后一个到第一个)
console.log("6");
});
app.listen(3000);
运行上述代码并在浏览器中访问 https://localhost:3000/
时,我们在控制台上得到以下输出。
1
3
5
6
4
2
这本质上就是 Koa 使用生成器的方式。 它允许我们使用此属性创建紧凑的中间件并为上游和下游功能编写代码,从而使我们免于回调。