JavaScript程序執行是單線程,既程序按順序一步一步向下執行,後面的程序必須等前面的程序執行完畢,這樣容易形成程序阻塞,浪費CPU資源,瀏覽器容易進入假死狀態(無響應),用戶體驗差,這時異步編程相應而出...ajax
回調函數是做爲函數參數形式來執行的, 它是最基礎的異步執行方法,讓咱們看一個例子,編程
定義三個函數,fun2利用setTimeout實現異步函數,執行結果分別是1,3,2數組
當咱們但願輸出1,2,3時,fun3輸出的順序依賴fun2時,咱們能夠把fun3做爲fun2的回掉函數promise
fun2(fun3)複製代碼
若後者等待前者的執行結果,採用這種方式,咱們把同步操做變成了異步操做,fun2便不會堵塞程序運行,至關於先執行程序的主要邏輯,將耗時的操做推遲執行。瀏覽器
promise
來下降異步編程的複雜性。
它每個異步任務返回一個Promise對象,該對象有一個then方法,容許指定回調函數,即:bash
fun2.then(fun3)
fun2.then(fun3).then(fun4)//能夠指定多個回掉函數
fun2.then(fun3).fail(fun4)//指定發生錯誤時的回調函數複製代碼
ES6規定,Promise對象是一個構造函數,用來生成Promise實例。Promise構造函數接受一個函數做爲參數,該函數的兩個參數分別是resolve
和reject
。它們是兩個函數,由JavaScript引擎提供,不用本身部署。異步
resolve函數負責把promise狀態從「未完成」到「完成」(Pending 到Resolved),且異步函數執行成功後把狀態做爲參數傳遞出去;reject函數把promise狀態從「未完成」到「失敗」async
Promise實例生成之後,能夠用then方法分別指定Resolved狀態和Reject狀態的回調函數。then方法接收兩個回掉函數做爲參數,一個是Promise對象爲Resolved狀態時調用,另外一個是爲Rejected(可選)狀態時調用。異步編程
promise.then(function(value) {
// success
}, function(value) {
// failure
});
複製代碼
then
方法返回的是一個新的Promise實例(注意,不是原來那個Promise實例)。所以能夠採用鏈式寫法,即then
方法後面再調用另外一個then
方法。函數
Promise.prototype.catch
方法是.then(null, rejection)
的別名,用於指定發生錯誤時的回調函數。
Promise.all
方法用於將多個Promise實例,包裝成一個新的Promise實例。Promise.all
方法接受一個數組做爲參數,每一個數組也是一個新到promise,當狀態都爲Resolve時,有一個爲rejected
,返回的promise狀態就變成rejected
async 會將其後的函數(函數表達式或 Lambda)的返回值封裝成一個 Promise 對象,而 await 會等待這個 Promise (也能夠是任意表達式)完成,並將其 resolve 的結果返回出來。
function fun1 () { console.log('1')}
function fun2 () { return new Promise((resolve, reject) => { setTimeout(() => { console.log('2') resolve() }, 500) })}
function fun3 () { console.log('3')}
async function asyncFun () { fun1() await fun2() fun3()}asyncFun()複製代碼