Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

简述一下 Generator 函数

传统的编程语言,早有异步编程的解决方案(其实是多任务的解决方案)。其中有一种叫做“协程”(coroutine),意思是多个线程互相协作,完成异步任务。

协程有点像函数,又有点像线程,它的运行流程大致如下:

  • 第一步,协程 A 开始执行;
  • 第二步,协程 A 执行到一半,进入暂停,执行权转移到协程 B
  • 第三步,(一段时间后)协程 B 交还执行权;
  • 第四步,协程 A 恢复执行;

上面流程的协程 A,就是异步任务,因为它分成两段(或多段)执行。

举例来说,读取文件的协程写法如下:

function* asyncJob() {
 // ...
 var f = yield readFile(fileA);
 // ...
}

上面代码的函数 asyncJob 是一个协程,它的奥妙就在其中的 yield 命令。它表示执行到此处,执行权将交给其他协程。也就是说,yield 命令是异步两个阶段的分界线。协程遇到 yield 命令就暂停,等到执行权返回,再从暂停的地方继续往后执行。

Generator 函数是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行)。

function* gen(x) {
  var y = yield x + 2;
  return y;
}

var g = gen(1);
g.next() // { value: 3, done: false }
g.next(2) // { value: 2, done: false }

next 是返回值的 value 属性,是 Generator 函数向外输出数据;next 方法还可以接受参数,向 Generator 函数体内输入数据。

上面代码中,第一个 next 方法的 value 属性,返回表达式 x + 2 的值 3。第二个 next 方法带有参数 2,这个参数可以传入 Generator 函数,作为 上个阶段 异步任务的返回结果,被函数体内的变量 y 接收。因此,这一步的 value 属性,返回的就是 2(变量 y 的值)。