聊一聊看似簡單的Promise.prototype.then()方法

Proise實例的then方法是定義在原型對象Promise.prototype上的,它的做用是爲Promise實例添加狀態改變時的回調函數。promise

該方法能夠接收兩個回調函數做爲參數,其中第二個回調函數是可選的。第一個回調函數是 Promise 對象的狀態變爲 Resolved 時調用,第二個回調函數是 Promise 對象的狀態變爲 Rejected 時調用。函數

下面從如下幾點進行說明:prototype

  1. then 方法返回的是一個Promise實例,可是須要注意的是並非原來調用它的那個Promise實例而是一個新的Promise實例。3d

    下面用代碼來講明:code

    let promise = new Promise( function (resolve, reject) {
        resolve();
        console.log("promise");
    });
    
    let promise_then = promise.then(function () {
     console.log("promise_then");    
    });
    
    promise_then.then(function () {
        console.log("promise_then_then")
    })
    
    // 運行結果:
    promise
    promise_then
    promise_then_then

    最早打印出 promise 的緣由是then方法的回調函數要在全部同步任務執行完後再執行,因此會先執行 console.log("promise") 而後再去執行下面then方法的回調函數。對象

    當程序執行到第6行結束時,promisepromise_then 的狀態以下圖所示:blog

在這裏插入圖片描述

可見then方法返回的是一個新的promise實例,而且此時promise_then的狀態爲 pending圖片

當執行完第8行時,promisepromise_then 的狀態以下圖所示:原型

在這裏插入圖片描述
可見此時 promise_then 的狀態變爲 resolved,也就是說只要then方法中的程序正常執行完不報錯,返回實例的狀態就變爲 resolved (這個地方緣由不是很清楚,若是有明白的,歡迎留言告知,謝謝哦)。回調函數

這個時候再往下執行 promise_then.then 就會打印出 promise_then_then

上面的代碼等價於

// ES5寫法
let promise = new Promise( function (resolve, reject) {
    resolve();
    console.log("promise");
});
promise.then(function () {
 console.log("promise_then");    
}).then(function () {
    console.log("promise_then_then")
});

// ES6寫法
let promise = new Promise( (resolve, reject) => {
    resolve();
    console.log("promise");
});
promise.then(
    () => console.log("promise_then")    
).then( 
    () => console.log("promise_then_then")
);
  1. then 方法中前一個回調函數的返回值能夠傳遞給下一個回調函數。

    1. 前一個回調函數的返回值是一個非promise實例時,比較簡單,看一下下面的代碼就很容易理解。
    let promise = new Promise( function (resolve, reject) {
        resolve();
    });
    promise.then(function () {
     return "aaa"; 
    }).then(function (data) {
        console.log(data);
    });
    // 輸出結果
    "aaa"
    1. 當前一個回調函數的返回值是一個promise實例時,下一個then方法的執行狀況要根據這個promise實例的狀態來執行。

      用下面的代碼來解釋一下:

    // 若是形參是'Resolved' -> 狀態爲‘Resolved’的promise實例
    // 若是形參是'Rejected' -> 狀態爲‘Rejected’的promise實例
    function createPromise(status) { 
        var p = new Promise(function (resolve, reject) {
            if (status === "Resolved") {
                resolve()
            } else {
                reject();
            }
        });
        return p;
    }
    
    createPromise("Resolved").then(function () {
        return createPromise("Rejected"); // 返回的promise實例的狀態是「Rejected」
    }).then(function () {
        console.log("前一個回調函數的返回值promise實例的狀態是'Resolved'");
    }, function () {
        console.log("前一個回調函數的返回值promise實例的狀態是'Rejected'");
    });
    // 輸出結果
    "前一個回調函數的返回值promise實例的狀態是'Rejected'"
    
    createPromise("Resolved").then(function () {
        return createPromise("Resolved"); // 返回的promise實例的狀態是「Resolved」
    }).then(function () {
        console.log("前一個回調函數的返回值promise實例的狀態是'Resolved'");
    }, function () {
        console.log("前一個回調函數的返回值promise實例的狀態是'Rejected'");
    });
    // 輸出結果:
    "前一個回調函數的返回值promise實例的狀態是'Resolved'"

    根據上面代碼的輸出結果能夠清晰地看到後一個回調函數的執行狀況是根據前一個回調函數返回的promise的狀態來執行的,若是返回的promise實例的狀態爲 Resolved ,那麼就執行第一個函數,若是返回的promise實例的狀態爲 Rejected ,那麼就執行第二個函數。

    完,若是不恰當之處,歡迎指正哦 。

相關文章
相關標籤/搜索