es6 Promise

https://www.jianshu.com/p/c98eb98bd00cjavascript

相信凡是寫過javascript的童鞋也必定都寫過回調方法(callback),簡單說回調方法就是將一個方法func2做爲參數傳入另外一個方法func1中,當func1執行到某一步或者知足某種條件的時候才執行傳入的參數func2,例以下面的代碼段html

// 當參數a大於10且參數func2是一個方法時 執行func2 function func1(a, func2) { if (a > 10 && typeof func2 == 'function') { func2() } } func1(11, function() { console.log('this is a callback') }) 

通常來講咱們會碰到的回調嵌套都不會不少,通常就一到兩級,可是某些狀況下,回調嵌套不少時,代碼就會很是繁瑣,會給咱們的編程帶來不少的麻煩,這種狀況俗稱——回調地獄。極端狀況以下圖:java

 
badcallback.jpeg

由此,Promise的概念就由社區提出並實現,做用與回調方法幾乎一致,都是在某種狀況下執行預先設定好的方法,可是使用它卻可以讓代碼變得更簡潔清晰編程

什麼是Promise

Promise是異步編程的一種解決方案,它有三種狀態,分別是pending-進行中resolved-已完成rejected-已失敗api

當Promise的狀態又pending轉變爲resolved或rejected時,會執行相應的方法,而且狀態一旦改變,就沒法再次改變狀態,這也是它名字promise-承諾的由來數組

ES6以前的Promise

在ES6中,Promise終於成爲了原生對象,能夠直接使用。可是在這以前,小夥伴們想要使用Promise,通常會藉助於第三方庫,或者當你知道其中的原理之後,也能夠手動實現一個簡易的Promisepromise

固然,爲了防止不可預知的bug,在生產項目中最好仍是不要使用原生的或者本身編寫的Promise(目前爲止並非全部瀏覽器都能很好的兼容ES6),而是使用已經較爲成熟的有大量小夥伴使用的第三方Promise庫,下面就爲小夥伴推薦一個—— Bluebird瀏覽器

Promise的基本用法

聲明一個Promise對象

// 方法1 let promise = new Promise ( (resolve, reject) => { if ( success ) { resolve(a) // pending ——> resolved 參數將傳遞給對應的回調方法 } else { reject(err) // pending ——> rejectd } } ) // 方法2 function promise () { return new Promise ( function (resolve, reject) { if ( success ) { resolve(a) } else { reject(err) } } ) } 

注意:實例化的Promise對象會當即執行異步

Promise.prototype.then() VS Promise.prototype.catch()

.then()方法使Promise原型鏈上的方法,它包含兩個參數方法,分別是已成功resolved的回調和已失敗rejected的回調異步編程

promise.then(
    () => { console.log('this is success callback') }, () => { console.log('this is fail callback') } ) 

.catch()的做用是捕獲Promise的錯誤,與then()的rejected回調做用幾乎一致。可是因爲Promise的拋錯具備冒泡性質,可以不斷傳遞,這樣就可以在下一個catch()中統一處理這些錯誤。同時catch()也可以捕獲then()中拋出的錯誤,因此建議不要使用then()的rejected回調,而是統一使用catch()來處理錯誤

promise.then(
    () => { console.log('this is success callback') } ).catch( (err) => { console.log(err) } ) 

一樣,catch()中也能夠拋出錯誤,因爲拋出的錯誤會在下一個catch中被捕獲處理,所以能夠再添加catch()

使用rejects()方法改變狀態和拋出錯誤 throw new Error() 的做用是相同的

當狀態已經改變爲resolved後,即便拋出錯誤,也不會觸發then()的錯誤回調或者catch()方法

then() 和 catch() 都會返回一個新的Promise對象,能夠鏈式調用

promise.then(
    () => { console.log('this is success callback') } ).catch( (err) => { console.log(err) } ).then( ... ).catch( ... ) 

Promise實例的異步方法和then()中返回promise有什麼區別?

// p1異步方法中返回p2 let p1 = new Promise ( (resolve, reject) => { resolve(p2) } ) let p2 = new Promise ( ... ) // then()中返回promise let p3 = new Promise ( (resolve, reject) => { resolve() } ) let p4 = new Promise ( ... ) p3.then( () => return p4 ) 

p1異步方法中返回p2

p1的狀態取決於p2,若是p2爲pending,p1將等待p2狀態的改變,p2的狀態一旦改變,p1將會當即執行本身對應的回調,即then()中的方法針對的依然是p1

then()中返回promise

因爲then()自己就會返回一個新的promise,因此後一個then()針對的永遠是一個新的promise,可是像上面代碼中咱們本身手動返回p4,那麼咱們就能夠在返回的promise中再次經過 resolve() 和 reject() 來改變狀態

Promise的其餘api

Promise.resolve() / Promise.reject()

用來包裝一個現有對象,將其轉變爲Promise對象,但Promise.resolve()會根據參數狀況返回不一樣的Promise:

參數是Promise:原樣返回
參數帶有then方法:轉換爲Promise後當即執行then方法
參數不帶then方法、不是對象或沒有參數:返回resolved狀態的Promise

Promise.reject()會直接返回rejected狀態的Promise

Promise.all()

參數爲Promise對象數組,若是有不是Promise的對象,將會先經過上面的Promise.resolve()方法轉換

var promise = Promise.all( [p1, p2, p3] ) promise.then( ... ).catch( ... ) 

當p一、p二、p3的狀態都變成resolved時,promise纔會變成resolved,並調用then()的已完成回調,但只要有一個變成rejected狀態,promise就會馬上變成rejected狀態

Promise.race()

var promise = Promise.race( [p1, p2, p3] ) promise.then( ... ).catch( ... ) 

「競速」方法,參數與Promise.all()相同,不一樣的是,參數中的p一、p二、p3只要有一個改變狀態,promise就會馬上變成相同的狀態並執行對於的回調

Promise.done() / Promise. finally()

Promise.done() 的用法相似 .then() ,能夠提供resolved和rejected方法,也能夠不提供任何參數,它的主要做用是在回調鏈的尾端捕捉前面沒有被 .catch() 捕捉到的錯誤

Promise. finally() 接受一個方法做爲參數,這個方法無論promise最終的狀態是怎樣,都必定會被執行

做者:君將來我已老 連接:https://www.jianshu.com/p/c98eb98bd00c 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
相關文章
相關標籤/搜索