promise

zlppassion發表於2020-04-22

1、什麼是Promise?

Promise是一個物件,儲存著非同步操作的結果(通常是非同步操作,也可以是同步操作),非同步操作結束後,會變更其狀態,然後呼叫註冊在then方法上的回撥函式。

promise
從圖中可以看到Promise建構函式的原型上分別掛載了thencatchfinally方法

2、先看簡單的用法

let promise = new Promise((resolve, reject) => {
    let a = Math.random()
    setTimeout(() => {
        if (a > 0.5) {
            resolve('success')
        } else {
            reject('error')
        }
    }, 1000)
})

promise.then(res => {
    console.log(res)
}).catch(err => {
    console.log(err)
})
複製程式碼

如果隨機數a大於0.5將會呼叫繫結在then方法上的回撥函式,並且列印出success,反之則列印出error

3、Promise的狀態

Promise有三種狀態:

  • pending: 初始狀態,既不是成功,也不是失敗狀態。
  • fulfilled: 意味著操作成功完成。
  • rejected: 意味著操作失敗。

pending狀態的promise可能會觸發fulfilled狀態或者rejected狀態,並傳入一個值給then方法,then方法包含了兩個引數(onfulfilled和onrejected),fulfilled狀態會呼叫onfulfilled方法,rejected狀態onrejected方法,即下面所示:

promise.then(function onfulfilled (res) {
    console.log(res)
},function onrejected (err){
    console.log(err)
})
複製程式碼

從第一張圖可以看到,then方法是定義在Promise的原型上的,原型上同時有catch方法,catch方法是 Promise.prototype.then(null, onrejected)或者Promise.prototype.then(undefined, onrejected)的別名

一般我們會才去catch方法來捕捉rejected狀態,這是因為onfulfilled如果有錯誤會被catch所捕捉到。

/ bad
promise.then(function(res) {
    // success
}, function(err) {
    // error
 });

// good
promise.then(function(res) {
    // success
}).catch(function(err) {
    // error
});
複製程式碼

3、new Promise的快捷方式

Promise.resolve(error) 是和 Promise.reject(value) 類似的靜態方法,是 new Promise() 方 法的快捷方式。

Promise.resolve(42)
// 可以認為是下面的語法糖
new Promise(function(resolve){ 
    resolve(42)
});

Promise.reject(new Error("出錯了")) 
// 可以認為是下面的語法糖
new Promise(function(resolve,reject){ 
    reject(new Error("出錯了"))
})
複製程式碼

4、Promise鏈式呼叫

promise
從圖中可以看到then方法可以鏈式呼叫,也就是在then方法後面可以接著寫then方法,這是因為then方法返回的是一個新的Promise例項,

那如何在then方法之間傳值呢,就是第一個then方法的值能夠傳遞給第二個then方法,以此類推,答案非常簡單,就是在then方法中return相應值就可以了

function doubleValue(value) { 
    return value * 2
}

function increment(value) {
    return value + 1
}
function output(value) { 
    console.log(value) // => (1 + 1) * 2
}
var promise = Promise.resolve(1); 
promise
    .then(increment) 
    .then(doubleValue) 
    .then(output) 
    .catch(function(error){
        // promise chain中出現異常的時候會被呼叫
        console.error(error)
    });
複製程式碼

整體流程:

  1. Promise.resolve(1); 傳遞 1 給 increment 函式
  2. 函式 increment 對接收的引數進行 +1 操作並返回(通過 return )
  3. 這時引數變為2,並再次傳給 doubleValue 函式
  4. 最後在函式 output 中列印結果

5、Promise.all

Promise.all 接收一個 promise物件的陣列作為引數,當這個陣列裡的所有promise物件 全部變為fulfilledrejected狀態的時候,它才會去呼叫 .then 方法。

6、Promise.race

Promise.all相對, Promise.race是隻要有一個promise物件進入 fulfilled 或者 rejected 狀態的話,就會繼續進行後面的處理。

如上整理,有誤請指正。

相關文章