你不知道的JavaScript(中卷)|Promise(三)

Promise API 概述


new Promise(..) 構(gòu)造器
有啟示性的構(gòu)造器Promise(..) 必須和new 一起使用,并且必須提供一個(gè)函數(shù)回調(diào)。這個(gè)回調(diào)是同步的或立即調(diào)用的。這個(gè)函數(shù)接受兩個(gè)函數(shù)回調(diào),用以支持promise 的決議。通常我們把這兩個(gè)函數(shù)稱為resolve(..) 和reject(..):

var p = new Promise(function(resolve, reject) {
    // resolve(..)用于決議/完成這個(gè)promise
    // reject(..)用于拒絕這個(gè)promise
});

reject(..) 就是拒絕這個(gè)promise;但resolve(..) 既可能完成promise,也可能拒絕,要根據(jù)傳入?yún)?shù)而定。如果傳給resolve(..) 的是一個(gè)非Promise、非thenable 的立即值,這個(gè)promise 就會(huì)用這個(gè)值完成。
但是,如果傳給resolve(..) 的是一個(gè)真正的Promise 或thenable 值,這個(gè)值就會(huì)被遞歸展開(kāi),并且(要構(gòu)造的)promise 將取用其最終決議值或狀態(tài)。

Promise.resolve(..) 和Promise.reject(..)
創(chuàng)建一個(gè)已被拒絕的Promise 的快捷方式是使用Promise.reject(..),所以以下兩個(gè)promise 是等價(jià)的:

var p1 = new Promise(function(resolve, reject) {
    reject("Oops");
});
var p2 = Promise.reject("Oops");

Promise.resolve(..) 常用于創(chuàng)建一個(gè)已完成的Promise,使用方式與Promise.reject(..)類似。但是,Promise.resolve(..) 也會(huì)展開(kāi)thenable 值(前面已多次介紹)。在這種情況下,返回的Promise 采用傳入的這個(gè)thenable 的最終決議值,可能是完成,也可能是拒絕:

var fulfilledTh = {
    then: function(cb) {
        cb(42);
    }
};
var rejectedTh = {
    then: function(cb, errCb) {
        errCb("Oops");
    }
};
var p1 = Promise.resolve(fulfilledTh);
var p2 = Promise.resolve(rejectedTh);
// p1是完成的promise
// p2是拒絕的promise

還要記住,如果傳入的是真正的Promise,Promise.resolve(..) 什么都不會(huì)做,只會(huì)直接把這個(gè)值返回。所以,對(duì)你不了解屬性的值調(diào)用Promise.resolve(..),如果它恰好是一個(gè)真正的Promise,是不會(huì)有額外的開(kāi)銷的。

then(..) 和catch(..)
每個(gè)Promise 實(shí)例(不是Promise API 命名空間)都有then(..) 和catch(..) 方法,通過(guò)這兩個(gè)方法可以為這個(gè)Promise 注冊(cè)完成和拒絕處理函數(shù)。Promise 決議之后,立即會(huì)調(diào)用這兩個(gè)處理函數(shù)之一,但不會(huì)兩個(gè)都調(diào)用,而且總是異步調(diào)用。
then(..) 接受一個(gè)或兩個(gè)參數(shù):第一個(gè)用于完成回調(diào),第二個(gè)用于拒絕回調(diào)。如果兩者中的任何一個(gè)被省略或者作為非函數(shù)值傳入的話,就會(huì)替換為相應(yīng)的默認(rèn)回調(diào)。默認(rèn)完成回調(diào)只是把消息傳遞下去,而默認(rèn)拒絕回調(diào)則只是重新拋出(傳播)其接收到的出錯(cuò)原因。

p.then( fulfilled );
p.then( fulfilled, rejected );
p.catch( rejected ); // 或者p.then( null, rejected )

Promise 局限性


順序錯(cuò)誤處理
Promise 的設(shè)計(jì)局限性(具體來(lái)說(shuō),就是它們鏈接的方式)造成了一個(gè)讓人很容易中招的陷阱,即Promise 鏈中的錯(cuò)誤很容易被無(wú)意中默默忽略掉。

單一值
根據(jù)定義,Promise 只能有一個(gè)完成值或一個(gè)拒絕理由。在簡(jiǎn)單的例子中,這不是什么問(wèn)題,但是在更復(fù)雜的場(chǎng)景中,你可能就會(huì)發(fā)現(xiàn)這是一種局限了。
一般的建議是構(gòu)造一個(gè)值封裝(比如一個(gè)對(duì)象或數(shù)組)來(lái)保持這樣的多個(gè)信息。這個(gè)解決方案可以起作用,但要在Promise 鏈中的每一步都進(jìn)行封裝和解封,就十分丑陋和笨重了。

其他promise知識(shí)點(diǎn)省略。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容