接觸Promise很久了,但一直也沒用過,感覺很陌生,但是ES2015來了,是時候使用了,本文將介紹Promise的方方面面,同時也是自己學習的過程。
本文將會盡可能使用ES2015的語法,這可能需要你使用一款現(xiàn)代瀏覽器,如果你還不了解可以閱讀下這篇文章。
Promise的瀏覽器兼容性如下,你需要選一款兼容的瀏覽器才可以,你也可以點擊這里查看。
Promise其實是Node社區(qū)中誕生的產物,如果你寫過Node你肯定會知道為了異步,寫了那么多的回調,而Promise就是比回調更有好的方式。
所謂Promise,就是一個對象,用來傳遞異步操作的消息。它代表了某個未來才會知道結果的事件(通常是一個異步操作),并且這個事件提供統(tǒng)一的API,可供進一步處理。
如果你有興趣可以閱讀一下Promise的規(guī)范,但我不太感興趣,我將從實踐的角度來學習它。
Promise是一個構造函數(shù)(類),可以使用new運算符新建一個實例,然后就可以使用了,構造函數(shù)接受一個函數(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對象時傳入的函數(shù),接受兩個參數(shù),resolve和reject,分別用來改變Promise的狀態(tài),創(chuàng)建好,調用resolve和reject時,可以傳入?yún)?shù),這個參數(shù)會自動傳遞個后面的回調函數(shù)中。
創(chuàng)建好promise后,可以通過then方法定制狀態(tài)變化后的回調函數(shù)。
好了這就是使用Promise的全部代碼了,剩下的部分就全靠你的發(fā)揮了,下面將會介紹常用的API。
打開瀏覽器的控制臺,輸入如下代碼:
Object.getOwnPropertyNames(Promise.prototype).sort().forEach(function (val) {console.log(val, '\n')});
在我的瀏覽器中上面的代碼會有如下輸出,可能不同瀏覽器會不一樣。
這里我們將重點關注如下接口:
catch() 方法只處理Promise被拒絕的情況,并返回一個Promise。該方法的行為和調用Promise.prototype.then(undefined, onRejected)相同。
p.catch((reason) => {
// 拒絕
});
更多信息,請點擊這里查看。
then()方法返回一個Promise。它有兩個參數(shù),分別為Promise在 success 和 failure 情況下的回調函數(shù)。
p.then((value) => {
// 滿足
}, (reason) => {
// 拒絕
});
更多信息,請點擊這里查看。
我們也先來看看瀏覽器支持哪些接口,在控制臺輸入如下代碼:
Object.getOwnPropertyNames(Promise).sort().forEach(function (val) {console.log(val, '\n')});
會看到如下的輸出:
我們將重點關注一下屬性:
Promise.all(iterable) 方法返回一個promise,該promise會在iterable參數(shù)內的所有promise都被解決后被解決。
Promise.all(iterable);
iterable是一個可迭代對象,比如Array。
更多信息,請點擊這里查看。
Promise.race(iterable)方法返回一個promise,這個promise在iterable中的任意一個promise被解決或拒絕后,立刻以相同的解決值被解決或以相同的拒絕原因被拒絕。
Promise.race(iterable);
iterable是一個可迭代對象,比如Array。
更多信息,請點擊這里查看。
Promise.reject(reason)方法返回一個用reason拒絕的Promise。
Promise.reject(reason);
reason Promise被拒絕的原因。
更多信息,請點擊這里查看。
Promise.resolve(value)方法返回一個以給定值resolve掉的Promise對象。但如果這個值是thenable的(就是說帶有then方法),返回的promise會“追隨”這個thenable的對象,接收它的最終狀態(tài)(指resolved/rejected/pendding/settled);否則這個被返回的promise對象會以這個值被fulfilled。
Promise.resolve(value);
Promise.resolve(promise);
Promise.resolve(thenable);
value 用來resolve待返回的promise對象的參數(shù)。既可以是一個Promise對象也可以是一個thenable。
更多信息,請點擊這里查看。
我們構造一段下面的代碼,基本上用到了上面的全部知識:
// 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了,類似的庫很多,我推薦使用es6-promise
es6-promise是一個兼容 ES6 Promises 的Polyfill類庫。 它基于 RSVP.js 這個兼容 Promises/A+ 的類庫, 它只是 RSVP.js 的一個子集,只實現(xiàn)了Promises 規(guī)定的 API。
關于使用方法和注意事項這個庫的文檔都寫得很詳細了,在此不再詳細介紹了。
是時候使用Promise了,上面已經介紹了ES2015 Promise的全部內容了,如果你還想閱讀更多資料,可查看下面的參考資料,如果你有任何疑問或建議,歡迎在下面的評論區(qū)和我討論。
原文網址:http://yanhaijing.com/javascript/2015/09/16/es6-promise/
本文對你有幫助?那就賞杯咖啡吧
微信掃一掃轉賬 支付寶掃一掃轉賬
更多建議: