Generator + co

Generator

Generator 函数是一个普通函数。

区别:

  1. function关键字与函数名之间有一个星号。(ES6 没有规定,function关键字与函数名之间的星号,写在哪个位置都能通过。)
  2. 函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。
  3. 调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,也就是遍历器对象(Iterator Object)。必须调用遍历器对象的 next() 方法,使得指针移向下一个状态
 function * helloWorldGenerator() {
     yield console.log('hello');
     yield console.log('world');
     return console.log('ending');
}

var hw = helloWorldGenerator();

— 控制台输入 hw.next();

hw.next();
index.html:156 hello

hw.next();
index.html:157 world

hw.next();
index.html:158 ending

必须调用遍历器对象的 next() 方法,使得指针移向下一个状态。每次调用next方法,内部指针就从上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。

换言之,Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。

上面代码定义了一个 Generator 函数helloWorldGenerator,它内部有两个yield表达式(hello和world),即该函数有三个状态:hello,world 和 return 语句(结束执行)。

yield 表达式

由于 Generator 函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield表达式就是暂停标志。

next方法

(1)遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

(2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield表达式。

(3)如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的属性值。

(4)如果该函数没有return语句,则返回的对象的value属性值为undefined。

yield表达式后面的表达式,只有当调用next方法、内部指针指向该语句时才会执行,因此等于为 JavaScript 提供了手动的“惰性求值”(Lazy Evaluation)的语法功能。

用途:

ajax的异步处理,需要等待别的异步成功后再执行

function* main() {
	...
    var result = yield request("http://www.xxx.com?rows=10&f={firstName}");
    console.log(result);
    //do 别的ajax请求;
}

co 是什么

co是用来自动执行generator函数的工具。generator的好处是可以在定义函数时候就打上“断点”,调用函数时候可以在断点的地方暂停函数的执行。Generator带来的问题是如何控制什么时候进行下一步调用。co可以解决这个问题。

特点:

1、co 模块,它基于 ES6 的 generator 和 yield ,能用同步的形式编写异步代码的nodejs模块。

代码如下:

const co = require ('co');

function* main() {
    执行代码。。。
});

co(main);

co 模块可以将异步解改成同步。co 函数接受一个 generator 函数作为参数,在函数内部自动执行 yield 。

co实现generator自动执行的条件

需要yield后面的数据类型为:

  • promises
  • thunks (functions)
  • array (parallel execution)
  • objects (parallel execution)
  • generators (delegation)
  • generator functions (delegation)

最后两种类型是官方建议避免使用的。

使用:

安装:

$ npm install co

index.js

function* helloWorldGenerator() {
   var a = Promise.resolve(1);
   var b = Promise.resolve(2);
   var c = Promise.resolve(3);
   var res = yield [a, b, c];
   console.log(res);
}

co(helloWorldGenerator).catch(onerror);
// 执行: [1, 2, 3]

function onerror(err) {
   console.error(err);
}
发布了121 篇原创文章 · 获赞 151 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/feifanzhuli/article/details/105086223