Promise
对象是一个代理对象(代理一个值),被代理的值在Promise对象建立时多是未知的。它容许你为异步操做的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法能够像同步方法那样返回值,但并非当即返回最终执行结果,而是一个能表明将来出现的结果的promise对象
若是遇到接口的调用参数依赖于上一个接口的返回值,咱们通常会这么写promise。es6
function getApi(params) { return new Promise((resolve) => { // 模拟ajax setTimeout(() => { resolve('api result: ' + params) }, 1000) }) } getApi('start').then((res) => { getApi(res).then((res) => { getApi(res).then((res) => { console.log('finish', res) }) }) })
promise的出现让异步方法能够像同步方法那样返回值,可是并无解决回调地狱的问题,如上面的场景,接下来就该Generator出场了。ajax
es6新增了一种声明方式,function *api
function*
这种声明方式(function
关键字后跟一个星号)会定义一个 生成器函数(generator function),它返回一个Generator
对象。生成器函数在执行时能暂停,后面又能从暂停处继续执行。promise
调用一个生成器函数并不会立刻执行它里面的语句,而是返回一个这个生成器的迭代器 ( iterator)对象。当这个迭代器的
next()
方法被首次(后续)调用时,其内的语句会执行到第一个(后续)出现yield
的位置为止,yield
后紧跟迭代器要返回的值。或者若是用的是yield*
(多了个星号),则表示将执行权移交给另外一个生成器函数(当前生成器暂停执行)。异步
next()
方法返回一个对象,这个对象包含两个属性:value 和 done,value 属性表示本次yield
表达式的返回值,done 属性为布尔类型,表示生成器后续是否还有yield
语句,即生成器函数是否已经执行完毕并返回。async调用
next()
方法时,若是传入了参数,那么这个参数会传给上一条执行的 yield语句左边的变量函数
运用生成器咱们就能够这样去改造上面的例子:
用生成器函数包裹咱们须要处理的语句,在yield后面跟咱们须要处理的promise函数,next()后会执行到下一个yield位置而后暂停当前生成器的执行,至于恢复的时机就是这个promise执行完成(fulfilled/rejected)的时候,这时再调用next(),继续执行生成器接下来的语句,这里咱们再实现一个自动运行生成器的方法。代理
function getApi(params) { return new Promise((resolve) => { // 模拟ajax setTimeout(() => { resolve('api result: ' + params) }, 1000) }) } function* gen(stage0) { console.log(stage0) let stage1 = yield getApi('startParams') console.log('stage1', stage1) let stage2 = yield getApi(stage1) console.log('stage2', stage2) let stage3 = yield getApi(stage2) console.log('stage3', stage3) return 'all Done!!' } function run(generator, v) { let { value, done } = generator.next(v) if (!done) { value.then((res) => { run(generator, res) }) } else { console.log(value) } } run(gen('start'))
es2017的新语法,对上面例子的改造就变成了code
function getApi(params) { return new Promise((resolve) => { // 模拟ajax setTimeout(() => { resolve('api result: ' + params) }, 1000) }) } async function getAllApi() { let stage1 = await getApi('startParams') console.log('stage1', stage1) let stage2 = await getApi(stage1) console.log('stage2', stage2) let stage3 = await getApi(stage2) console.log('stage3', stage3) return 'all Done!!' } getAllApi()
因此说async/await
就是generator
+ promise
的语法糖,还自带auto run的buff对象