快來使用ES2015的Promise吧

2018-06-16 20:34 更新

接觸Promise很久了,但一直也沒用過,感覺很陌生,但是ES2015來了,是時(shí)候使用了,本文將介紹Promise的方方面面,同時(shí)也是自己學(xué)習(xí)的過程。

閱讀須知

本文將會(huì)盡可能使用ES2015的語法,這可能需要你使用一款現(xiàn)代瀏覽器,如果你還不了解可以閱讀下這篇文章

兼容性

Promise的瀏覽器兼容性如下,你需要選一款兼容的瀏覽器才可以,你也可以點(diǎn)擊這里查看。

什么是Promise

Promise其實(shí)是Node社區(qū)中誕生的產(chǎn)物,如果你寫過Node你肯定會(huì)知道為了異步,寫了那么多的回調(diào),而Promise就是比回調(diào)更有好的方式。

所謂Promise,就是一個(gè)對(duì)象,用來傳遞異步操作的消息。它代表了某個(gè)未來才會(huì)知道結(jié)果的事件(通常是一個(gè)異步操作),并且這個(gè)事件提供統(tǒng)一的API,可供進(jìn)一步處理。

如果你有興趣可以閱讀一下Promise的規(guī)范,但我不太感興趣,我將從實(shí)踐的角度來學(xué)習(xí)它。

new Promise

Promise是一個(gè)構(gòu)造函數(shù)(類),可以使用new運(yùn)算符新建一個(gè)實(shí)例,然后就可以使用了,構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù)。

var p = new Promise((resolve, reject) => {
    window.setTimeout(() => {resolve(123);}, 1000);
});

p.then((data) => {
    console.log('p success', data);
});

上面的代碼輸出如下:

=> p success 123

新建Promise對(duì)象時(shí)傳入的函數(shù),接受兩個(gè)參數(shù),resolve和reject,分別用來改變Promise的狀態(tài),創(chuàng)建好,調(diào)用resolve和reject時(shí),可以傳入?yún)?shù),這個(gè)參數(shù)會(huì)自動(dòng)傳遞個(gè)后面的回調(diào)函數(shù)中。

創(chuàng)建好promise后,可以通過then方法定制狀態(tài)變化后的回調(diào)函數(shù)。

好了這就是使用Promise的全部代碼了,剩下的部分就全靠你的發(fā)揮了,下面將會(huì)介紹常用的API。

Promise.prototype 屬性

打開瀏覽器的控制臺(tái),輸入如下代碼:

Object.getOwnPropertyNames(Promise.prototype).sort().forEach(function (val) {console.log(val, '\n')});

在我的瀏覽器中上面的代碼會(huì)有如下輸出,可能不同瀏覽器會(huì)不一樣。

這里我們將重點(diǎn)關(guān)注如下接口:

  • catch
  • then

Promise.prototype.catch

catch() 方法只處理Promise被拒絕的情況,并返回一個(gè)Promise。該方法的行為和調(diào)用Promise.prototype.then(undefined, onRejected)相同。

p.catch((reason) => {
   // 拒絕
});

更多信息,請(qǐng)點(diǎn)擊這里查看

Promise.prototype.then

then()方法返回一個(gè)Promise。它有兩個(gè)參數(shù),分別為Promise在 success 和 failure 情況下的回調(diào)函數(shù)。

p.then((value) => {
   // 滿足
  }, (reason) => {
  // 拒絕
});

更多信息,請(qǐng)點(diǎn)擊這里查看。

Promise 屬性

我們也先來看看瀏覽器支持哪些接口,在控制臺(tái)輸入如下代碼:

Object.getOwnPropertyNames(Promise).sort().forEach(function (val) {console.log(val, '\n')});

會(huì)看到如下的輸出:

我們將重點(diǎn)關(guān)注一下屬性:

  • all
  • race
  • reject
  • resolve

Promise.all

Promise.all(iterable) 方法返回一個(gè)promise,該promise會(huì)在iterable參數(shù)內(nèi)的所有promise都被解決后被解決。

Promise.all(iterable);

iterable是一個(gè)可迭代對(duì)象,比如Array。

更多信息,請(qǐng)點(diǎn)擊這里查看。

Promise.race

Promise.race(iterable)方法返回一個(gè)promise,這個(gè)promise在iterable中的任意一個(gè)promise被解決或拒絕后,立刻以相同的解決值被解決或以相同的拒絕原因被拒絕。

Promise.race(iterable);

iterable是一個(gè)可迭代對(duì)象,比如Array。

更多信息,請(qǐng)點(diǎn)擊這里查看

Promise.reject

Promise.reject(reason)方法返回一個(gè)用reason拒絕的Promise。

Promise.reject(reason);

reason Promise被拒絕的原因。

更多信息,請(qǐng)點(diǎn)擊這里查看

Promise.resolve

Promise.resolve(value)方法返回一個(gè)以給定值resolve掉的Promise對(duì)象。但如果這個(gè)值是thenable的(就是說帶有then方法),返回的promise會(huì)“追隨”這個(gè)thenable的對(duì)象,接收它的最終狀態(tài)(指resolved/rejected/pendding/settled);否則這個(gè)被返回的promise對(duì)象會(huì)以這個(gè)值被fulfilled。

Promise.resolve(value);
Promise.resolve(promise);
Promise.resolve(thenable);

value 用來resolve待返回的promise對(duì)象的參數(shù)。既可以是一個(gè)Promise對(duì)象也可以是一個(gè)thenable。

更多信息,請(qǐng)點(diǎn)擊這里查看

實(shí)戰(zhàn)

我們構(gòu)造一段下面的代碼,基本上用到了上面的全部知識(shí):

// 1000ms 后success
var p1 = new Promise((resolve, reject) => {
    window.setTimeout(() => {resolve(123);}, 1000);
});

p1.then((data) => {
    console.log('p1 success', data);
});

// 2000ms 后success
var p2 = new Promise((resolve, reject) => {
    window.setTimeout(() => {resolve(456);}, 2000);
}); 

p2.then((data) => {
    console.log('p2 success', data);
});

var pa = Promise.all([p1, p2]);
var pr = Promise.race([p1, p2]);

pa.then((data) => {
    console.log('pa success', data);
});

pr.then((data) => {
    console.log('pr success', data);
});

上面的代碼輸出如下:

// 1000ms
p1 success 123
pr success 123

// 2000ms
p2 success 456
pa success [123, 456]

Polyfill

如果要兼容舊的瀏覽器,又要使用新特性,那么只能使用Polyfill了,類似的庫很多,我推薦使用es6-promise

es6-promise是一個(gè)兼容 ES6 Promises 的Polyfill類庫。 它基于 RSVP.js 這個(gè)兼容 Promises/A+ 的類庫, 它只是 RSVP.js 的一個(gè)子集,只實(shí)現(xiàn)了Promises 規(guī)定的 API。

關(guān)于使用方法和注意事項(xiàng)這個(gè)庫的文檔都寫得很詳細(xì)了,在此不再詳細(xì)介紹了。

總結(jié)

是時(shí)候使用Promise了,上面已經(jīng)介紹了ES2015 Promise的全部內(nèi)容了,如果你還想閱讀更多資料,可查看下面的參考資料,如果你有任何疑問或建議,歡迎在下面的評(píng)論區(qū)和我討論。

參考資料

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)