一、Promise
promise的出现是为了解决回调地狱问题。什么是回调地狱呢?
例如:使用jquery的ajax请求省市区的数据,请求市数据的接口依赖省的数据,请求区数据的接口依赖市的数据,这样我们必须在ajax成功的回调里再写请求。这种方式嵌套了多层请求,形成了三角结构,代码十分冗余,并且后期难以维护。
// 获取省市区的数据
$.ajax({
type: 'get/post',
url: 'www.baidu.com',
dataType: 'json/jsonp',
success: function(res) {
console.log('省')
$.ajax({
...
success: function(res) {
console.log('市')
$.ajax({
...
success: function(res) {
console.log('区')
}
})
}
})
}
})
promise怎么解决回调地狱问题的呢?下面的代码中可以看出,promise解决了回调地狱的问题,形成一个上下结构,链式调用。
new Promise((resolve, reject) =>{
resolve('省')
}).then(res =>{
setTimeout(() => {console.log(res)}, 1000)
return new Promise((resolve, reject) => {
resolve('市')
})
}).then(res => {
setTimeout(() => {console.log(res)}, 1000)
return new Promise((resolve, reject) => {
resolve('区')
})
}).then(res => {
setTimeout(() => {console.log(res)}, 1000)
})
promise的两个API:all(等所有的执行完返回结果)和race(谁快返回谁)
let promise1 = Promise.resolve('1212')
let promise2 = new Promise((resolve) => {
setTimeout(() => {resolve('3434')}, 1000)
})
Promise.all([promise1, promise2]).then(res => {
console.log(res) // ['1212', '3434']
})
Promise.race([promise1, promise2]).then(res => {
console.log(res) // '1212'
})
二、Genetator
promise虽然解决了回调地狱问题,但是它本身也存在回调问题,有嵌套的层级,所以又衍生出genetator。genetator需要搭配yield使用,并且每次执行都需要.next(),一次next()返回两个值,value为返回的结果,done表示当前genetator是否执行完成。
function *gen() {
yield Promise.resolve('省')
yield Promise.resolve('市')
yield Promise.resolve('区')
}
let g = gen()
console.log(g.next()) // { value: Promise { '省' }, done: false }
三、Async/await
为了解决genetator需要每次next()的问题,出现了async。async是genetator的语法糖。既解决了链式调用的问题,又不存在需要每次都需要next()调用。
// async = genetator + next()
async function asy () {
await new Promise((resolve) => {
setTimeout(() => {console.log(1)}, 1000)
})
await new Promise((resolve) => {
setTimeout(() => {console.log(2)}, 1000)
})
await new Promise((resolve) => {
setTimeout(() => {console.log(3)}, 1000)
})
}