Promise要點(diǎn)記錄

1.什么是Promise?
Promise是抽象異步處理對象以及對其進(jìn)行各種操作的組件。
2.三種類型
Constructor是其中一種:

Promise類似于 XMLHttpRequest,從構(gòu)造函數(shù) Promise 來創(chuàng)建一個(gè)新建新promise對象作為接口。

要想創(chuàng)建一個(gè)promise對象、可以使用new來調(diào)用Promise的構(gòu)造器來進(jìn)行實(shí)例化。

var promise = new Promise(function(resolve, reject) {
    // 異步處理
    // 處理結(jié)束后、調(diào)用resolve 或 reject
});
//可以使用then,catch實(shí)例化:
成功resolve():
promise.then(onFulfilled, onRejected)
失敗reject()有兩種寫法,后者更直觀:
promise.then(undefined, onRejected)  == promise.catch(onRejected)

3.Promise創(chuàng)建和處理方法:

  • new Promise 方法創(chuàng)建promise對象

  • .then.catch 添加promise對象的處理函數(shù)

4.new Promise() 方法的快捷方式
靜態(tài)方法Promise.resolve(value) 可以認(rèn)為是 new Promise() 方法的快捷方式。

###比如 Promise.resolve(42); 可以認(rèn)為是以下代碼的語法糖。

new Promise(function(resolve){
    resolve(42);
});
###方法 Promise.resolve(value); 的返回值也是一個(gè)promise對象,所以我們可以像下面那樣接著對其返回值進(jìn)行 .then 調(diào)用。

Promise.resolve(42).then(function(value){
    console.log(value);
});

5.Promise方法鏈

aPromise.then(function taskA(value){
// task A
}).then(function taskB(vaue){
// task B
}).catch(function onRejected(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);
}
function finalTask() {
    console.log("Final Task");
}

var promise = Promise.resolve();
promise
    .then(taskA)
    .then(taskB)
    .catch(onRejected)
    .then(finalTask);
image.png

6.不管是 then 還是 catch 方法調(diào)用,都返回了一個(gè)新的promise對象。
6.1 我們說過 .catch 也可以理解為 promise.then(undefined, onRejected) 。
then不能進(jìn)行錯(cuò)誤處理的onRejected

function throwError(value) {
    // 拋出異常
    throw new Error(value);
}
// <1> onRejected不會被調(diào)用
function badMain(onRejected) {
    return Promise.resolve(42).then(throwError, onRejected);
}
// <2> 有異常發(fā)生時(shí)onRejected會被調(diào)用
function goodMain(onRejected) {
    return Promise.resolve(42).then(throwError).catch(onRejected);
}
// 運(yùn)行示例
badMain(function(){
    console.log("BAD");
});
goodMain(function(){
    console.log("GOOD");
});
在上面的代碼中, badMain 是一個(gè)不太好的實(shí)現(xiàn)方式(但也不是說它有多壞), goodMain 則是一個(gè)能非常好的進(jìn)行錯(cuò)誤處理的版本。
為什么說 badMain 不好呢?,因?yàn)殡m然我們在 .then 的第二個(gè)參數(shù)中指定了用來錯(cuò)誤處理的函數(shù),但實(shí)際上它卻不能捕獲第一個(gè)參數(shù) onFulfilled 指定的函數(shù)(本例為 throwError )里面出現(xiàn)的錯(cuò)誤。
也就是說,這時(shí)候即使 throwError 拋出了異常,onRejected 指定的函數(shù)也不會被調(diào)用(即不會輸出"BAD"字樣)。
與此相對的是, goodMain 的代碼則遵循了 throwError→onRejected 的調(diào)用流程。 這時(shí)候 throwError 中出現(xiàn)異常的話,在會被方法鏈中的下一個(gè)方法,即 .catch 所捕獲,進(jìn)行相應(yīng)的錯(cuò)誤處理。
.then 方法中的onRejected參數(shù)所指定的回調(diào)函數(shù),實(shí)際上針對的是其promise對象或者之前的promise對象,而不是針對 .then 方法里面指定的第一個(gè)參數(shù),即onFulfilled所指向的對象,這也是 then 和 catch 表現(xiàn)不同的原因。

``

2.10.2. 總結(jié)

這里我們又學(xué)習(xí)到了如下一些內(nèi)容。

  1. 使用promise.then(onFulfilled, onRejected) 的話

    • onFulfilled 中發(fā)生異常的話,在 onRejected 中是捕獲不到這個(gè)異常的。
  2. promise.then(onFulfilled).catch(onRejected) 的情況下

    • then 中產(chǎn)生的異常能在 .catch 中捕獲
  3. .then.catch 在本質(zhì)上是沒有區(qū)別的

    • 需要分場合使用。

我們需要注意如果代碼類似 badMain 那樣的話,就可能出現(xiàn)程序不會按預(yù)期運(yùn)行的情況,從而不能正確的進(jìn)行錯(cuò)誤處理。

7.使用 reject 會比使用 throw 安全
在 then 中使用reject的方法
8.then原理
在 then 中注冊的回調(diào)函數(shù)可以通過 return 返回一個(gè)值,這個(gè)返回值會傳給后面的 then 或 catch 中的回調(diào)函數(shù)。

而且return的返回值類型不光是簡單的字面值,還可以是復(fù)雜的對象類型,比如promise對象等。
這時(shí)候,如果返回的是promise對象的話,那么根據(jù)這個(gè)promise對象的狀態(tài),在下一個(gè) then 中注冊的回調(diào)函數(shù)中的onFulfilled和onRejected的哪一個(gè)會被調(diào)用也是能確定的。

也許實(shí)際中我們可能不常使用 reject ,但是比起來不假思索的使用 throw 來說,使用 reject 的好處還是很多的。

var promise = Promise.resolve();
promise.then(function () {
    var retPromise = new Promise(function (resolve, reject) {
        // resolve or reject 的狀態(tài)決定 onFulfilled or onRejected 的哪個(gè)方法會被調(diào)用
    });
    return retPromise;
}).then(onFulfilled, onRejected);
###后面的then調(diào)用哪個(gè)回調(diào)函數(shù)是由promise對象的狀態(tài)來決定的

也就是說,這個(gè) retPromise 對象狀態(tài)為Rejected的時(shí)候,會調(diào)用后面then中的 onRejected 方法,這樣就實(shí)現(xiàn)了即使在 then 中不使用 throw 也能進(jìn)行reject處理了。

var onRejected = console.error.bind(console);
var promise = Promise.resolve();
promise.then(function () {
    var retPromise = new Promise(function (resolve, reject) {
       reject(new Error("this promise is rejected"));
    });
    return retPromise;
}).catch(onRejected);
//簡寫
var onRejected = console.error.bind(console);
var promise = Promise.resolve();
promise.then(function () {
    return Promise.reject(new Error("this promise is rejected"));
}).catch(onRejected);

推薦原文:http://liubin.org/promises-book/#promise-sequence

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

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