Promise:javascript
Promise爲了解決異步回調地獄而生的,其解決方法就是鏈式調用promise.then()或promise.all();java
Promise有兩個參數,resolve和reject,第一個表明正確的返回處理,第二個表明異常的返回處理!數組
function promise1(){ let num = 0; return new Promise((resolve,reject)=>{ setTimeout(()=>{ num++; resolve(num); },3000); }); } promise1().then((num)=>{ console.log(num); });
3秒後輸出結果是1。promise
then方法裏有兩個參數,第一個是resolve,第二個是reject,resolve能夠返回一個promise,也能夠直接返回一個data,直接返回的data會做爲接下來的then裏的resolve的形參傳遞。異步
function promise1(){ let num = 0; return new Promise((resolve,reject)=>{ setTimeout(()=>{ num++; resolve(num); },3000); }); } function promise2(num){ let p = new Promise((resolve,reject)=>{ setTimeout(()=>{ num+=3; resolve(num); },3000); }); return p; } function promise3(num){ let p = new Promise((resolve,reject)=>{ setTimeout(()=>{ num *= num; resolve(num); },3000); }); return p; } promise1().then((num)=>{ console.log(num); return promise2(num); }).then((num)=>{ console.log(num); return promise3(num); }).then((num)=>{ console.log(num); return 3; }).then((num)=>{ console.log(num); }).then((num)=>{ console.log(num); });
輸出結果async
第4個then直接返回第三個then返回的數字3,而最後一個num形參沒有傳遞任何數據,故是undefined。函數
Promise的all方法提供了並行執行異步操做的能力,而且在全部異步操做執行完後才執行回調,注意這個相似是靜態方法,直接經過Promise.all關鍵詞調用測試
Promise.all([promise1(),promise2(2),promise3(6)]).then((result)=>{
console.log(result);
});
結果:spa
用Promise.all來執行,all接收一個數組參數,裏面的值最終都返回Promise對象。這樣,三個異步操做的並行執行的,等到它們都執行完後纔會進到then裏面。那麼,三個異步操做返回的數據哪裏去了呢?都在then裏面呢,all會把全部異步操做的結果放進一個數組中傳給then,就是上面的resultscode
還有個race方法,all方法的效果其實是「誰跑的慢,以誰爲準執行回調」,那麼相對的就有另外一個方法「誰跑的快,以誰爲準執行回調」,這就是race方法,這個詞原本就是賽跑的意思。
promise的這種鏈式調用能夠很好的解決回調地獄的問題!
async、await
這兩個玩意解決異步回調簡直是完美!
async只能放到函數前面,await只能出如今標有async的函數裏,意思就是等待!async函數和正常的function同樣使用,若是內部有await 那麼能夠拋出錯誤處理
async function timeout(){ let cc = await func(); } timeout().catch(error){ console.log(error); }
await能夠使當前代碼暫停執行,等到await 後的代碼處理完後再繼續向下執行,await後的方法返回的是Promise對象,也能夠是本身定義的含有then方法的對象
function promiseAwt(num){ let p = new Promise((resolve,reject)=>{ setTimeout(()=>{ let cnt = 0; while(num > 0){ cnt += num; num--; } resolve(cnt); },num); }); return p; } async function timeout(){ let cc = await promiseAwt(3000); console.log('道德經'); let dd = await promiseAwt(1000); console.log("天之道"); let ee = await promiseAwt(2000); console.log(`cc:${cc}\ndd:${dd}\nee:${ee}`); } timeout(); console.log("我先執行");
輸出結果
若是現場試驗你會發現,先輸出 「我先執行」 等待3秒輸出「道德經」,再等待1秒輸出‘天之道’,再等待2秒輸出累加的和 cc、dd、ee,程序在執行await的時候等待了!
await 最後獲得的值就是promise的resolve傳遞過來的參數!
下面是綜合測試:
function promise1(){ let num = 0; return new Promise((resolve,reject)=>{ setTimeout(()=>{ num++; resolve(num); },3000); }); } function promise2(num){ let p = new Promise((resolve,reject)=>{ setTimeout(()=>{ num+=3; resolve(num); },3000); }); return p; } function promise3(num){ let p = new Promise((resolve,reject)=>{ setTimeout(()=>{ num *= num; resolve(num); },3000); }); return p; } Promise.all([promise1(),promise2(2),promise3(6)]).then((result)=>{ console.log(result); }); function promiseAwt(num){ let p = new Promise((resolve,reject)=>{ setTimeout(()=>{ let cnt = 0; while(num > 0){ cnt += num; num--; } resolve(cnt); },num); }); return p; } async function timeout(){ let cc = await promiseAwt(3000); console.log('道德經'); let dd = await promiseAwt(1000); console.log("天之道"); let ee = await promiseAwt(2000); console.log(`cc:${cc}\ndd:${dd}\nee:${ee}`); promise1().then((num)=>{ console.log("sssss:"+num); return promise2(num); }).then((num)=>{ console.log("nnnn:"+num); return promise3(num); }).then((num)=>{ console.log("hello world----"+num); }); } timeout(); console.log("我先執行");
輸出結果