一:Generator
Generator 函数是一个普通函数,但是有两个特征。一是,function
关键字与函数名之间有一个星号;二是,函数体内部使用yield
表达式,输出不同的内部状态。
执行 Generator 函数会返回一个遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
Generator 函数的调用方法与普通函数一样,也是在函数名后面加上一对圆括号。不同的是,调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象。然后,必须调用遍历器对象的next
方法,使得指针移向下一个状态。也就是说,每次调用next
方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield
表达式(或return
语句)为止。换言之,Generator 函数是分段执行的,yield
表达式是暂停执行的标记,而next
方法可以恢复执行。
二:生成器与迭代
Generator 函数就是遍历器生成函数,因此可以把 Generator 赋值给对象的Symbol.iterator
属性,从而使得该对象具有 Iterator 接口。而 Generator中使用yield语句输出被迭代的内容即可。
三:next方法可传参
通过next
方法的参数,就有办法在 Generator 函数开始运行之后,继续向函数体内部注入值。也就是说,可以在 Generator 函数运行的不同阶段,从外部向内部注入不同的值,从而调整函数行为。
四:生成器的异步应用
ES6 以前,异步编程的方法,大概有下面四种。
- 回调函数
- 事件监听
- 发布/订阅
- Promise 对象
Generator可以通过yield分段执行,其实就是让出cpu使用权,这种特性十分适合用来实现协程。
整个 Generator 函数就是一个封装的异步任务的容器。异步操作需要暂停的地方,都用yield
语句让出使用权。
next
方法的作用是分阶段执行Generator
函数,继续执行异步任务。
五:async 函数
async 函数是 Generator 函数的语法糖,进行了更友好的包装。
async
函数就是将 Generator 函数的星号(*
)替换成async
,将yield
替换成await
,仅此而已。
var asyncTask = async function () { do... await(异步操作); do... await(异步操作); ...... };
async
函数对 Generator 函数作出改进:
(1)内置执行器。
Generator 函数的执行必须靠执行器,而async
函数自带执行器,该函数一旦被调用就自动执行。
(2)返回值是 Promise。
async
函数的返回值是 Promise 对象,你可以用then
方法指定下一步的操作。
进一步说,async
函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await
命令就是内部then
命令的语法糖。
应用例子:
async function getStockPriceByName(name) { var symbol = await getStockSymbol(name); var stockPrice = await getStockPrice(symbol); return stockPrice; } getStockPriceByName('goog').then(function (result) { console.log(result); });