Promise 其實很簡單

修行的人生發表於2019-03-25

Promise 是什麼?

Promise 的定義

A Promise is an object representing the eventual completion or failure of an asynchronous operation. Essentially, a promise is a returned object you attach callbacks to, instead of passing callbacks into a function.

Promise 是一個表示非同步操作最終完成或失敗的物件,可以直接向其新增回撥函式,而不必將回撥函式傳進方法。

Promise 有三種狀態:Pending、Fullfilled、Rejected。初始是 Pendding 狀態,表示非同步操作正在執行。呼叫 resolve 方法可以讓其狀態從 Pending 變為 Fullfilled,此時 then 方法中的第一個回撥函式被觸發;呼叫 reject 方法可以讓其狀態從 Pending 變為 Rejected 狀態,此時 then 方法中的第二個回撥函式被觸發。

Promise 的簡單使用

使用方法

const promise = new Promise(function(resolve, reject) {
    // 非同步操作,返回之後
        // 判斷非同步操作的結果
        if (/* 成功 */) {
            resolve("Fullfilled");
        } else {            reject("Rejected");
        }
})

promise.then(onFullfilled, onRejected)
             .catch(e => handleError(e));

// 非同步操作成功的回撥
function onFullfilled(result) {
    console.log(result);
}

// 非同步操作失敗的回撥
function onRejected(reason) {
    console.log(reason);
}

// 異常處理函式
function handleError(e) {
    throw new Error("Error");
}
複製程式碼

Promise 封裝 XMLHttpRequest

看下面一個封裝 XMLHttpRequest 物件的例子:

const getJSON = function (url) {

    const promise = new Promise(function(resolve, reject){

        const handler = function () {

            if (this.readyState !== 4) {

                return;

            }

            if (this.status === 200) {

                resolve(this.response);

            } else {

                reject(new Errer(this.statusText));

            }

        };

        const client = new XMLHttpRequest();

        client.open("GET", url);

        client.onreadystatechange = handler;

        client.responseType = "json";

        client.setRequestHeader("Accept", "application/json");

        client.send();

    });

};

getJSON("posts.json").then(function(json){

    console.log('Contents: ' + json);

}, function(error){

    console.log(error);

});
複製程式碼

鏈式呼叫

function taskA() {
    console.log("Task A");
}
function taskB() {
    console.log("Task B");
}
function onRejected(error) {
    console.log("Catch Error: A or B", error);
}

var promise = Promise.resolve();
promise
    .then(taskA)
    .then(taskB)
    .catch(onRejected) // 捕獲前面then方法中的異常

複製程式碼

Promise 的靜態方法 all

All 方法用於多個獨立的非同步操作,對多個非同步操作的結果做彙總。

const p1 = new Promise((resolve, reject) => {
    resolve(1);
})

const p2 = new Promise((resolve, reject) => {
    resolve(2);
});

const p3 = new Promise((resolve, reject) => {
    resolve(3);
});

Promise.all([p1, p2, p3]).then(data => { 
    console.log(data); //  [1, 2, 3] 結果順序和promise例項陣列順序是一致的
}, err => {
    console.log(err);
});

複製程式碼

Promise 的靜態方法 race

Promise.race 只要有一個 Promise 物件進入 Fullfilled 或 Rejected 狀態,Promise 就進入相應的狀態。

function timerPromisefy(delay) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            resolve(delay);
        }, delay);
    });
}

Promise.race([
    timerPromisefy(10),
    timerPromisefy(20),
    timerPromisefy(30)
]).then(function (values) {
    console.log(values); // 10
});
複製程式碼

說白了,Promise 就是一個包含了非同步操作結果的物件,它可以根據結果來決定該執行哪個回撥函式。

結論

本質的本質,Promise 就是一個組織非同步操作的工具。以前用回撥函式處理非同步的時候是這樣流程:
(1)執行非同步操作 ——》(2)非同步返回 ——》(3)回撥函式
現在用 Promise 的流程是這樣的:
(1)執行非同步操作 ——》(2)非同步返回 ——》(3)Promise 的物件方法和靜態方法 ——》(4)回撥函式
在第三步中我們有了更多的選擇,可以對非同步操作進行進一步的管理和組織,因此使得非同步操作邏輯更加易於維護。
所以,Promise 很簡單,就是一個管理非同步操作的工具。

參考文章:
Promise 原理講解
JavaScript: Promises explained with simple real life analogies

相關文章