Generator函数-《ES6 入门教程》阮一峰学习笔记

477 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情

前言

Generator函数之前,异步的解决方案有回调函数、事件监听、发布/订阅以及Promise函数。Generator 函数将 JavaScript 异步编程带入了一个全新的阶段。

关于异步的概念可移步 Promise对象-《ES6 入门教程》阮一峰学习笔记观看

Generator 函数

协程

在讲Generator 函数之前,我们先来讲讲协程这个概念。它是一种异步编程的解决方案,从字面上理解就是多个线程共同协作完成异步任务。

运行流程:

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

而在Generator 函数函数就是协程函数,它通过yield命令来暂停某个协程,执行其它线程,通过Generator 函数来实现异步就可以避免回调地狱的问题。

实现

function *cal(x){
  let a=yield 1+2
  let b=yield x+3
  return b
}
let result=cal(2)
console.log(result.next())  //{ value: 3, done: false }
console.log(result.next())  //{ value: 5, done: false }
console.log(result.next())//{ value: undefined, done: true }  代表指针指到末尾,之后都是返回这个

在上述代码中

1.我们看到Generator函数的形式是一个函数,不过相对于普通函数有两点不同。一是在function关键字和函数名称之间多了’*'号;二是函数内部使用了yield表达式,用于定义Generator函数中的每个状态。

2.调用 Generator 函数,会返回一个内部指针(即遍历器)cal。这是 Generator 函数不同于普通函数的另一个地方,即执行它不会返回结果,返回的是指针对象。调用指针calnext方法,会移动内部指针(即执行异步任务的第一段),指向第一个遇到的yield语句,上例是执行到x + 3为止。

换言之,next方法的作用是分阶段执行Generator函数。每次调用next方法,会返回一个对象,表示当前阶段的信息(value属性和done属性)。value属性是yield语句后面表达式的值,表示当前阶段的值;done属性是一个布尔值,表示 Generator 函数是否执行完毕,即是否还有下一个阶段。当执行完毕,valueundefineddonetrue之后再调用next都是输出这个。

错误处理

function* cal(x) {
  try {
    var y = yield x + 3
  } catch (e) {
    console.log(e)
  }
}
let result = cal(2)
console.log(result.next())   //{ value: 5, done: false }
console.log(result.next())//{ value: undefined, done: false }
console.log(result.throw("Error"));  //Error ...

总结

Generator函数目前来讲用得不多,因为切换到下个状态还要调用next方法,要是协程很多就显得麻烦。在之后的ES版本的async函数解决了这个问题,简单来说就是使函数自动执行,这些我们在之后会讲到