Promise、Generator函數、yield、async/await 相關html
今有一題,題目爲:前端
ajax1()
和ajax2()
,用於快速初始化CODE1和CODE2僞代碼爲:ajax
Ajax1({ ... success: function(data){ CODE1 = data } }) Ajax1({ ... success: function(data){ CODE1 = data } }) myFunc(CODE1, CODE2)
做爲一個後端,我最早想到的是建立一個變量來標誌兩個ajax是否完成,而後再兩個ajax的回調中進行判斷(至於兩個ajax都改成同步這種方法直接不考慮),大體代碼以下:後端
使用了setTimeOut
來模擬ajax:數組
let CODE1 = null let CODE2 = null function myFunc() { console.log(CODE1, CODE2); } //第一種 let flag = 0 //flag默認爲0 function ajax1() { setTimeout(() => { console.log('ajax1獲得響應') CODE1 = 'ajax1返回的數據' //若是回調時flag爲1,表明另外一個ajax已經初始化成功 if (flag === 1) { myFunc() } else { //不然flag+1表明本ajax成功 flag += 1 } }, 1000) } function ajax2() { setTimeout(() => { console.log('ajax2獲得響應') CODE2 = 'ajax2返回的數據' if (flag === 1) { myFunc() } else { flag += 1 } }, 2000) } ajax1() ajax2()
執行結果:promise
能夠看到myFunc在兩個ajax執行完成以後才執行。async
yield關鍵字是ES6添加的語法,能夠在函數執行中交出運行權限函數
上面第一種方法一看就是不會前端的人寫的,前端若是要想炫技的話能夠這麼寫:code
//第二種 //Promise執行器 function run(gen) { gen = gen() return next(gen.next()) function next({ done, value }) { return new Promise(resolve => { if (done) { resolve(value) } else { value.then(data => { next(gen.next(data)).then(resolve) }) } }) } } function ajax1() { return new Promise(resolve => { setTimeout(() => { console.log('ajax1獲得響應'); CODE1 = 'ajax1返回的數據' resolve() }, 5000) }) } function ajax2() { return new Promise(resolve => { setTimeout(() => { console.log('ajax2獲得響應'); CODE2 = 'ajax2返回的數據' resolve() }, 5000) }) } function* call() { let aj1 = ajax1() let aj2 = ajax2() yield aj1 yield aj2 } run(call).then(myFunc)
什麼意思我解釋不清楚,也不想解釋,本身去看阮一峯的博客:Generator 函數的含義與用法htm
async/await關鍵字是ES7的語法,是對上面Promise執行器的一種簡化:
// 第三種 function ajax1() { return new Promise(resolve => { setTimeout(() => { console.log('ajax1獲得響應'); CODE1 = 'ajax1返回的數據' resolve() }, 1000) }) } function ajax2() { return new Promise(resolve => { setTimeout(() => { console.log('ajax2獲得響應'); CODE2 = 'ajax2返回的數據' resolve() }, 2000) }) } async function call() { /* 這裏不能這麼寫: await ajax1() await ajax2() 這樣會在ajax1以後纔會執行ajax2 須要寫成下面的這種: */ let aj1 = ajax1() let aj2 = ajax2() await aj1 await aj2 myFunc() } call()
async聲明這是一個內部存在同步的函數,只有聲明瞭async,函數內部才能使用await,await表明等待Promise執行完畢纔會繼續執行,的確有點同步的感受了。
上面用到了Promise可是都沒介紹,就是想把最合適的一種放到最後:
//第四中,同時也是最優解 function ajax1(resolve, reject) { setTimeout(()=>{ console.log('ajax1獲得響應'); CODE1 = 'ajax1返回的數據' resolve() },1000) } function ajax2(resolve, reject) { setTimeout(()=>{ console.log('ajax2獲得響應'); CODE2 = 'ajax2返回的數據' resolve() },2000) } const p1 = new Promise(ajax1) const p2 = new Promise(ajax2) Promise.all([p1, p2]).then(myFunc)
函數Promise.all()
接收一個Promise數組參數,做用是數組內的Promise執行完畢以後會返回一個Promise對象。(還有一個Promise.race()
方法也挺好玩,做用是參數中任意一個Promise完成就返回一個Promise)