Promise
Promise
对象是一个代理对象(代理一个值),被代理的值在Promise对象创建时可能是未知的。它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象
常用场景
如果遇到接口的调用参数依赖于上一个接口的返回值,我们一般会这么写promise。
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出场了。
Generator
es6新增了一种声明方式,function *
function*
这种声明方式(function
关键字后跟一个星号)会定义一个生成器函数(generator function),它返回一个Generator
对象。生成器函数在执行时能暂停,后面又能从暂停处继续执行。
调用一个生成器函数并不会马上执行它里面的语句,而是返回一个这个生成器的迭代器 ( iterator)对象。当这个迭代器的
next()
方法被首次(后续)调用时,其内的语句会执行到第一个(后续)出现yield
的位置为止,yield
后紧跟迭代器要返回的值。或者如果用的是yield*
(多了个星号),则表示将执行权移交给另一个生成器函数(当前生成器暂停执行)。
next()
方法返回一个对象,这个对象包含两个属性:value 和 done,value 属性表示本次yield
表达式的返回值,done 属性为布尔类型,表示生成器后续是否还有yield
语句,即生成器函数是否已经执行完毕并返回。调用
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'))
async/await
es2017的新语法,对上面例子的改造就变成了
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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。