Promise 學習筆記

xiaopi發表於2018-03-22

什麼是 Promise

ES6 原生提供了 Promise 建構函式,用以解決非同步程式設計中的回撥地獄問題。該建構函式返回一個 Promise 例項,可以看作一個容器,儲存著未來結束的某個事件的結果。

Promise 有三種狀態:pending(進行中)、fulfilled(成功)、rejected(失敗)。

每個 Promise 都會經歷一個短暫的生命週期,操作成功 pending 變成 fulfilled,操作失敗 pending 變成 rejected。只要這兩種情況發生,狀態就不會再變了。

基本用法

通過 new 操作符就可以例項化一個 Promise 物件,建構函式接收一個函式作為引數,這個過程是同步的,函式裡面的程式碼會立即執行。

let p = new Promise(function (resolve, reject) {
    console.log(1);
});
console.log(2);
// => 1
// => 2
複製程式碼

該函式的兩個引數 resolve 和 reject,分別可以將 Promise 的狀態從 pending 變成 fulfilled 和 rejected。

let p = new Promise(function (resolve, reject) {
    if (/*非同步操作成功*/) {
        resolve(data); // pending 變成 fulfilled
    } else {
        reject(error); // pending 變成 rejected
    }
});
複製程式碼

then()

Promise 的原型物件具有 then 方法(Promise.prototype.then),供 Promise 例項呼叫。then 方法的第一個引數是 resolve 狀態的回撥函式,如果不需要,可以傳 null。第二個引數是 reject 狀態的回撥函式,可以省略。

let p = new Promise(function (resolve, reject) {
    setTimeout(() => {
        resolve('Hello!');
    }, 2000);
});
p.then(data => {
    console.log(data);
}, error => {
    console.log(error);
});
// 等待兩秒...
// => 'Hello!'
複製程式碼

then 方法支援鏈式操作,它的返回值是一個新的 Promise。如果一個 then 的回撥函式的返回值是 Promise,那麼下一個 then 會在該 Promise 狀態改變後再被呼叫。

let p = new Promise(function (resolve, reject) {
    setTimeout(() => {
        resolve('Hello!');
    }, 2000);
});
p.then(data => {
    console.log(data);
    return new Promise(function (resolve, reject) {
        setTimeout(() => {
            resolve('World!');
        }, 2000);
    });
}).then(data => {
    console.log(data);
});
// 等待兩秒...
// => 'Hello!'
// 等待兩秒...
// => 'World!'
複製程式碼

catch()

catch 同樣是 Promise 原型物件的方法(Promise.prototype.catch),用於指定發生錯誤時的回撥函式,該回撥函式等同於 then 的第二個引數。

let p = new Promise(function (resolve, reject) {
    setTimeout(() => {
        resolve('Hello!');
    }, 2000);
});
p.then(data => {
    throw new Error('第一個錯誤');
}).then(data => {
    throw new Error('第二個錯誤');
}).catch(error => {
    console.log(error);
});
// 等待兩秒...
// => Error: 第一個錯誤
複製程式碼

all()

all 是 Promise 的靜態方法(Promise.all)。它能夠將多個 Promise 例項包裝成一個新的 Promise 例項。新例項的狀態由原來多個例項的狀態決定,原例項都變成 fulfilled,新例項才會變成 fulfilled。只要有一個原例項變成 rejected,新例項也會變成 rejected。

race()

和 all 方法一樣,race 也是 Promise 的靜態方法(Promise.race)。它同樣能將多個 Promise 例項包裝成一個新的 Promise 例項。不同的是,只要原例項有一個改變了狀態,新例項就立刻改變狀態,第一個做出改變的原例項的返回值傳遞給新例項的回撥函式。

相關文章