想想,咱們以前是怎麼處理異步編程的(回調函數和事件),基於回調函數的異步編程一般代碼冗雜,層層嵌套,不易於維護,甚至可能形成‘回調地獄’的慘狀。
Promise則是另一種異步編程的方案,它比回調函數更優雅美觀,也更易於維護。起初有各大社區實現Promise的功能,到ES6的時候,TC39將Promise方案寫進了標準之中,統一實現,在原生的層面上實現了Promise。編程
這邊參照阮大大的想法,咱們能夠把Promise理解成一個容器,容器會保存異步操做(好比http請求或者定時器setTimeout)的結果(resolved或rejected),咱們能夠經過Promise的相關方法獲取異步操做的完成結果或者捕獲其錯誤。數組
Promise通常有一下三種狀態可能:pending,fullfilled(resolved),rejected,以及兩種狀態過渡: fullfilled 到 resolved,fullfilled到rejected。因此promise對象通常有兩種結果狀態:1. resolved(完成),2.rejected(失敗),並且Promise的結果狀態是肯定以後就沒法改變的。promise
promise對象由Promise構造函數實例後生成。bash
const pro = new Promise( (resolve,reject) => {
// xhr 請求
// 請求成功後 resolve 結果
// 請求遇到問題 reject 錯誤信息
})
複製代碼
Promsie構造器接收一個帶有resolve和reject兩個參數(也是函數)的函數(一般裏面包含了異步操做)。實例化構造函數時,會直接調用該函數,異步操做也將會被觸發。異步
當異步操做取得結果時,咱們能夠resolve這個promise實例,將promise的狀態從fullfilled轉變爲resolved,並將結果做爲參數傳遞給promise實例。 一樣若是異步操做發生錯誤時,咱們能夠reject這個promise實例,將promise的狀態從fullfilled轉爲rejected狀態,並將錯誤信息做爲參數傳遞給promise實例。async
promise對象提供了then和catch方法(Promise原型鏈上的方法),方便咱們對promise狀態發生改變時,對所接受到的信息進行處理。異步編程
pro.then( res => {
// 這裏的res就是resolve該promise時所傳遞的數據
console.log(res);
})
.catch(error => {
// 這裏的error就是reject該promise時所捕獲的錯誤信息
console.log(error);
})
複製代碼
then方法須要傳遞一個函數,當promise狀態變爲resolved時,將會調用該函數,並將傳遞的數據做爲參數。同理promise狀態變爲rejected時,catch的方法會被調用,且promise中捕獲的錯誤將會被做爲參數。函數
注意:ui
then方法返回的是一個promise對象,具體返回的promise取決於then方法中的回調函數的返回值。由於這種機制,因此promise能夠鏈式調用then方法,也就能夠將依賴前一個異步結果的then方法返回,而後繼續處理。 then方法的返回依據參考 mdn文檔 then方法返回值spa
注意:
catch方法會捕獲其以前在promise鏈式調用時拋出的錯誤,而不單單只是promise自己拋出的錯誤。 還有一點,promise內部的錯誤若是不被reject,錯誤不會被顯性得拋出,catch也得不到錯誤信息。
catch方法會返回一個promise,因此其後面也可使用鏈式調用。
pro
.then(res => {
// 這裏的res就是resolve該promise時所傳遞的數據
console.log(res);
const pro1 = new Promise((resolve, reject) => {
// 一些 xhr 請求
// 請求成功後 resolve
// 請求遇到問題 reject
});
return pro1
})
.then(res1 => {
// 這裏處理 pro1成功處理的相關數據
console.log(res1);
})
.catch(error => {
// 這裏的error就是promise鏈式調用時所拋出的錯誤信息
console.log(error);
});
複製代碼
Promise.all
const p = Promise.all([p1, p2, p3]);
複製代碼
all方法須要傳入一組promise實例做爲參數,all方法自己會返回一個promise實例(p),p的狀態取決於傳入的promise組。
Promise.race
const p = Promise.race([p1, p2, p3]);
複製代碼
與all類似,須要傳入promise組,可是p的狀態改變模式不太同樣。 promise組中任意一個promise狀態變爲resolved時,race方法返回的promise將會把狀態改成resolved。
Promise.allSettled(兼容性較差)
const p = Promise.allSettled([p1, p2, p3]);
複製代碼
與all類似,須要傳入promise組,可是p的狀態改變模式也不太同樣。 p將會在promise組中全部promise從fullfilled狀態轉變爲rejected或resolved時,轉變爲resolved轉態,promise組返回值或者拋出的錯誤以數組的方式傳遞給p。
Promise.resolve()
const p = Promise.resolve();
複製代碼
簡單來講,resolve方法返回是promise對象,具體須要看傳入的參數是什麼
Promise.reject()
const p = Promise.reject();
複製代碼
reject方法會返回一個狀態爲rejected的promise對象,reject值爲方法傳入的參數。
好了,到這裏已經把Promise比較基礎的部分都梳理了一遍,若是有不懂或者有問題的部分能夠評論!複製代碼