Koa.js - 生成器



JavaScript ES6 最令人兴奋的新特性之一是新型函数——生成器。在生成器出现之前,整个脚本通常按照自上而下的顺序执行,没有简单的方法来停止代码执行并在稍后使用相同的堆栈恢复执行。生成器是可以退出并在以后重新进入的函数。它们的上下文(变量绑定)将在重新进入时保存。

生成器允许我们在中途停止代码执行。因此,让我们来看一个简单的生成器。

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。然后它返回一个包含value和done的对象,其中value具有表达式的值。这个表达式可以是任何东西。此时,它暂停执行。当我们再次调用此函数(next)时,生成器从上次yield点恢复执行,函数状态与暂停时的状态相同,直到下一个yield点。这将持续到代码中没有更多yield点为止。

Koa中的生成器

为什么我们在本教程中讨论生成器?您可能还记得在hello world程序中,我们使用function* ()表示法将回调传递给app.use()。Koa是一个对象,它包含一个中间件生成器函数数组,所有这些函数都在每次请求时以堆栈式方式组合和执行。Koa还实现了控制流的下游和上游。

请看下面的例子,以便更好地理解这一点。

var koa = require('koa');
var app = koa();
 
app.use(function* (next) {
   //do something before yielding to next generator function 
   
   //in line which will be 1st event in downstream
   console.log("1");
   yield next;
 
   //do something when the execution returns upstream, 
   //this will be last event in upstream
   console.log("2");
});
app.use(function* (next) {
   // This shall be 2nd event downstream
   console.log("3");
   yield next;
 
   // This would be 2nd event upstream
   console.log("4");
});
app.use(function* () { 
   // Here it would be last function downstream
   console.log("5");
   
   // Set response body
   this.body = "Hello Generators";

   // First event of upstream (from the last to first)
   console.log("6");
});

app.listen(3000);

运行以上代码并导航到https://127.0.0.1:3000/,我们在控制台中得到以下输出。

1
3
5
6
4
2

这基本上就是Koa如何使用生成器。它允许我们利用此特性创建紧凑的中间件,并为上游和下游功能编写代码,从而使我们免于回调。

广告