(1)創(chuàng)建Promise對象
Promise對象代表一個異步操作,有三種狀態(tài):pending(進行中)、fulfilled(已成功)和rejected(已失敗)。
Promise構(gòu)造函數(shù)接受一個函數(shù)作為參數(shù),該函數(shù)的兩個參數(shù)分別是resolve和reject。
一般情況下都會使用new Promise()來創(chuàng)建promise對象,但是也可以使用promise.resolve和promise.reject這兩個方法:
Promise.resolve
Promise.resolve(value)的返回值也是一個promise對象,可以對返回值進行.then調(diào)用,代碼如下:
resolve(11)代碼中,會讓promise對象進入確定(resolve狀態(tài)),并將參數(shù)11傳遞給后面的then所指定的onFulfilled 函數(shù);
創(chuàng)建promise對象可以使用new Promise的形式創(chuàng)建對象,也可以使用Promise.resolve(value)的形式創(chuàng)建promise對象;
Promise.reject
Promise.reject 也是new Promise的快捷形式,也創(chuàng)建一個promise對象。代碼如下:
就是下面的代碼new Promise的簡單形式:
下面是使用resolve方法和reject方法:
上面的代碼的含義是給testPromise方法傳遞一個參數(shù),返回一個promise對象,如果為true的話,那么調(diào)用promise對象中的resolve()方法,并且把其中的參數(shù)傳遞給后面的then第一個函數(shù)內(nèi),因此打印出 “hello world”, 如果為false的話,會調(diào)用promise對象中的reject()方法,則會進入then的第二個函數(shù)內(nèi),會打印No thanks;
(2)Promise方法
Promise有五個常用的方法:then()、catch()、all()、race()、finally。下面就來看一下這些方法。
then()
當Promise執(zhí)行的內(nèi)容符合成功條件時,調(diào)用resolve函數(shù),失敗就調(diào)用reject函數(shù)。Promise創(chuàng)建完了,那該如何調(diào)用呢?
then方法可以接受兩個回調(diào)函數(shù)作為參數(shù)。第一個回調(diào)函數(shù)是Promise對象的狀態(tài)變?yōu)閞esolved時調(diào)用,第二個回調(diào)函數(shù)是Promise對象的狀態(tài)變?yōu)閞ejected時調(diào)用。其中第二個參數(shù)可以省略。
then方法返回的是一個新的Promise實例(不是原來那個Promise實例)。因此可以采用鏈式寫法,即then方法后面再調(diào)用另一個then方法。
當要寫有順序的異步事件時,需要串行時,可以這樣寫:
那當要寫的事件沒有順序或者關(guān)系時,還如何寫呢?可以使用all 方法來解決。
2. catch()
Promise對象除了有then方法,還有一個catch方法,該方法相當于then方法的第二個參數(shù),指向reject的回調(diào)函數(shù)。不過catch方法還有一個作用,就是在執(zhí)行resolve回調(diào)函數(shù)時,如果出現(xiàn)錯誤,拋出異常,不會停止運行,而是進入catch方法中。
all()
all方法可以完成并行任務(wù), 它接收一個數(shù)組,數(shù)組的每一項都是一個promise對象。當數(shù)組中所有的promise的狀態(tài)都達到resolved的時候,all方法的狀態(tài)就會變成resolved,如果有一個狀態(tài)變成了rejected,那么all方法的狀態(tài)就會變成rejected。
調(diào)用all方法時的結(jié)果成功的時候是回調(diào)函數(shù)的參數(shù)也是一個數(shù)組,這個數(shù)組按順序保存著每一個promise對象resolve執(zhí)行時的值。
(4)race()
race方法和all一樣,接受的參數(shù)是一個每項都是promise的數(shù)組,但是與all不同的是,當最先執(zhí)行完的事件執(zhí)行完之后,就直接返回該promise對象的值。如果第一個promise對象狀態(tài)變成resolved,那自身的狀態(tài)變成了resolved;反之第一個promise變成rejected,那自身狀態(tài)就會變成rejected。
那么race方法有什么實際作用呢?當要做一件事,超過多長時間就不做了,可以用這個方法來解決:
finally()
finally方法用于指定不管 Promise 對象最后狀態(tài)如何,都會執(zhí)行的操作。該方法是 ES2018 引入標準的。
上面代碼中,不管promise最后的狀態(tài),在執(zhí)行完then或catch指定的回調(diào)函數(shù)以后,都會執(zhí)行finally方法指定的回調(diào)函數(shù)。
下面是一個例子,服務(wù)器使用 Promise 處理請求,然后使用finally方法關(guān)掉服務(wù)器。
finally方法的回調(diào)函數(shù)不接受任何參數(shù),這意味著沒有辦法知道,前面的 Promise 狀態(tài)到底是fulfilled還是rejected。這表明,finally方法里面的操作,應(yīng)該是與狀態(tài)無關(guān)的,不依賴于 Promise 的執(zhí)行結(jié)果。finally本質(zhì)上是then方法的特例:
上面代碼中,如果不使用finally方法,同樣的語句需要為成功和失敗兩種情況各寫一次。有了finally方法,則只需要寫一次。