一、Promise
promise的出現是為了解決回調地獄問題。什么是回調地獄呢?
例如:使用jquery的ajax請求省市區(qū)的數據,請求市數據的接口依賴省的數據,請求區(qū)數據的接口依賴市的數據,這樣我們必須在ajax成功的回調里再寫請求。這種方式嵌套了多層請求,形成了三角結構,代碼十分冗余,并且后期難以維護。
// 獲取省市區(qū)的數據
$.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('區(qū)')
}
})
}
})
}
})
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('區(qū)')
})
}).then(res => {
setTimeout(() => {console.log(res)}, 1000)
})
promise的兩個API:all(等所有的執(zhí)行完返回結果)和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使用,并且每次執(zhí)行都需要.next(),一次next()返回兩個值,value為返回的結果,done表示當前genetator是否執(zhí)行完成。
function *gen() {
yield Promise.resolve('省')
yield Promise.resolve('市')
yield Promise.resolve('區(qū)')
}
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)
})
}