国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Promise初級(jí)與進(jìn)階---都在這了

Ocean / 2078人閱讀

摘要:處理和前一個(gè)回調(diào)函數(shù)運(yùn)行時(shí)發(fā)生的錯(cuò)誤發(fā)生錯(cuò)誤對(duì)象的錯(cuò)誤具有冒泡性質(zhì),會(huì)一直向后傳遞,直到被捕獲為止。

0 前言

我一直以為我對(duì)Promise比較了解,相關(guān)的方法已經(jīng)非常熟悉了,直到我看到這篇文章,里面提出了這樣一個(gè)問題:
Q: 假定 doSomething() 和 doSomethingElse() 均返回 promises,下面的四種 promises 的區(qū)別是什么

        //1
        doSomething().then(function(){
            return doSomethingElse();
        }).then(finalHandler);
        
        //2
        doSomething().then(function(){
            doSomethingElse();
        }).then(finalHandler);
        
        //3
        doSomething().then(doSomethingElse())
        .then(finalHandler);
        
        //4
        doSomething().then(doSomethingElse)
        .then(finalHandler);

我當(dāng)時(shí)看了是吃驚的,因?yàn)槲蚁?,這都什么玩意兒!??!所以我把Promise的方法復(fù)習(xí)了一遍,并且仔細(xì)讀了上面提到的那篇文章,于是就有了這篇文章。

在前端開發(fā)的學(xué)習(xí)中,新工具層出不窮,理解當(dāng)前的基礎(chǔ)是要理解過去,然后了解將來。就異步調(diào)用而言,ES6中引入Promise簡(jiǎn)化異步操作,主要針對(duì)的問題就是回調(diào)函數(shù)的層層嵌套(金字塔問題),除了閱讀不方便之外,只能在當(dāng)前回調(diào)函數(shù)函數(shù)內(nèi)部處理異常,這個(gè)很難做。Promise通過then和catch方法實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用,每一次調(diào)用都返回一個(gè)Promise對(duì)象,擺脫了回調(diào)函數(shù)層層嵌套的問題和異步代碼“非線性執(zhí)行”的問題;另外,所有回調(diào)函數(shù)的報(bào)錯(cuò)都可以通過Promise統(tǒng)一處理,catch可以捕獲先前調(diào)用中所有的異常(冒泡特性)。但是Promise僅僅是對(duì)回調(diào)做了簡(jiǎn)化處理,ES7中的async函數(shù)更厲害,結(jié)合Promise,完全不用回調(diào)函數(shù),以近似同步的寫法實(shí)現(xiàn)異步操作,所需要的僅僅是一個(gè)async和await關(guān)鍵字而已。本文僅介紹Promise對(duì)象,以及ES6中Promise對(duì)象具有的一些操作方法。

1 簡(jiǎn)單Promise對(duì)象

ES6中原生實(shí)現(xiàn)了Promise對(duì)象,通過狀態(tài)傳遞異步操作的消息。Promise對(duì)象有三種狀態(tài):pending(進(jìn)行中)、resoleved(fulfilled,已完成)、rejected(已失敗),根據(jù)異步操作的結(jié)果決定處于何種狀態(tài)。一旦狀態(tài)改變就不可再變,狀態(tài)改變僅有兩種pending=>rejected、pending=>resolved。
優(yōu)點(diǎn):避免了層層嵌套的回調(diào)函數(shù),并提供了統(tǒng)一的接口,使異步操作更加容易。
缺點(diǎn):無法取消Promise;如果不設(shè)置回調(diào)函數(shù),內(nèi)部錯(cuò)誤無法反映到外部。

1.1 創(chuàng)建Promise實(shí)例

Promise構(gòu)造函數(shù)接收兩個(gè)參數(shù):resolve和reject,這是兩個(gè)由JavaScript引擎自動(dòng)提供的函數(shù),不用自己部署。resolve函數(shù)在異步操作成功時(shí)調(diào)用,作用是將Promise對(duì)象的狀態(tài)由pending變?yōu)閞esolved,并將異步操作的結(jié)果傳遞出去。reject函數(shù)在異步操作失敗時(shí)調(diào)用,作用是將Promise對(duì)象的狀態(tài)由pending變?yōu)閞eject,將異步操作報(bào)錯(cuò)傳遞出去。
then方法可以接受兩個(gè)回調(diào)函數(shù)作為參數(shù),第一個(gè)是Pormise對(duì)象的狀態(tài)變?yōu)閞esolved時(shí)調(diào)用,另一個(gè)是當(dāng)Promise對(duì)象的狀態(tài)變?yōu)閞ejected時(shí)調(diào)用,這兩個(gè)回調(diào)函數(shù)都接受Promise對(duì)象實(shí)例創(chuàng)建過程中resolve函數(shù)和reject函數(shù)傳出的值作為參數(shù)。第二個(gè)參數(shù)可選,事實(shí)上一般通過Promise.prototype.catch()調(diào)用發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù),通過then調(diào)用異步操作成功時(shí)的回調(diào)函數(shù)。
實(shí)例1:

        //返回Promise對(duì)象,setTimeout中傳遞的resolve參數(shù)為’done’
        function timeout(ms) {
          return new Promise((resolve, reject) => {
            setTimeout(resolve, ms, "done");
          });
        }
        
        timeout(100).then((value) => {
          console.log(value);
        }); //done

實(shí)例2:Promise執(zhí)行流

        //創(chuàng)建Promise實(shí)例
        let promise = new Promise(function(resolve, reject) {
          console.log("Promise");//立即執(zhí)行
          resolve();
        });
        //resolved狀態(tài)調(diào)用在當(dāng)前腳本所有同步任務(wù)執(zhí)行完才會(huì)執(zhí)行
        promise.then(function() {
          console.log("Resolved.");
        });
        //立即執(zhí)行
        console.log("Hi!");

對(duì)以上代碼,Promise新建后立即執(zhí)行,所以首先輸出的是“Promise”。然后,then方法指定的回調(diào)函數(shù),將在當(dāng)前腳本所有同步任務(wù)執(zhí)行完才會(huì)執(zhí)行,所以“Resolved”最后輸出。

reject函數(shù)在異步操作失敗時(shí)調(diào)用,因此參數(shù)常常是一個(gè)錯(cuò)誤對(duì)象(Error Object);resolve函數(shù)在操作成功時(shí)調(diào)用,參數(shù)常常是正常值或者另一個(gè)Promise實(shí)例,這表征了異步嵌套,異步嵌套的外層Promise要等待內(nèi)層Promise的狀態(tài)決定下一步狀態(tài)。

        var p1 = new Promise(function (resolve, reject) {
          setTimeout(() => reject(new Error("fail")), 3000)
        })
        
        var p2 = new Promise(function (resolve, reject) {
          setTimeout(() => resolve(p1), 1000)
        })

        p2.then(result => console.log(result)) //p1 is rejected, p2 is the same as p1
          .catch(error => console.log(error)) // Error: fail

由于p2的resolve方法將p1作為參數(shù),p1的狀態(tài)決定了p2的狀態(tài),如果p1的狀態(tài)是pending,p2的回調(diào)函數(shù)會(huì)等待p1的狀態(tài)改變;如果p1的狀態(tài)是resolved或rejected,p2的回調(diào)函數(shù)立即執(zhí)行。p2的狀態(tài)在1秒之后改變,resolve方法返回的是p1。此時(shí),由于p2返回的是另一個(gè)Promise,所以后面的then語句都變成針對(duì)后者(p1)。又過了2秒,p1變?yōu)閞ejected,導(dǎo)致觸發(fā)catch方法指定的回調(diào)函數(shù)。

1.2 Promise.prototype.then()

then方法為Promise實(shí)例添加狀態(tài)改變時(shí)的回調(diào)函數(shù),返回一個(gè)新的Promise實(shí)例,可以采用鏈?zhǔn)綄懛?,前一個(gè)then方法的返回值作為后一個(gè)then方法的參數(shù):

        getJSON("/posts.json").then(function(json) {  // json comes from “/posts.json”
          return json.post;
         }).then(function(post) {  //post comes from json.post
          // ...
        });

如果第一個(gè)then方法內(nèi)的回調(diào)函數(shù)返回一個(gè)Promise對(duì)象,后續(xù)的then方法會(huì)根據(jù)這個(gè)新的Promise對(duì)象的狀態(tài)執(zhí)行回調(diào)函數(shù)。

        getJSON("/post/1.json").then(function(post) {
          return getJSON(post.commentURL);
        }).then(function funcA(comments) {
          console.log("Resolved: ", comments);
        }, function funcB(err){
          console.log("Rejected: ", err);
        });

第一個(gè)then方法指定的回調(diào)函數(shù),返回的是另一個(gè)Promise對(duì)象。這時(shí),第二個(gè)then方法指定的回調(diào)函數(shù),就會(huì)等待這個(gè)新的Promise對(duì)象狀態(tài)發(fā)生變化。如果變?yōu)镽esolved,就調(diào)用funcA,如果狀態(tài)變?yōu)镽ejected,就調(diào)用funcB。回調(diào)函數(shù)一般是匿名函數(shù),上述僅僅是為了便于理解寫成命名函數(shù)。

1.3 Promise.prototype.catch()

catch(rejection)方法是then(null,rejection)的別稱,僅僅當(dāng)發(fā)生錯(cuò)誤時(shí)執(zhí)行,catch的存在是將錯(cuò)誤回調(diào)函數(shù)從then()方法中剝離出來。

        getJSON("/posts.json").then(function(posts) {
          // ...
        }).catch(function(error) {
          // 處理 getJSON 和 前一個(gè)回調(diào)函數(shù)運(yùn)行時(shí)發(fā)生的錯(cuò)誤
          console.log("發(fā)生錯(cuò)誤!", error);
        });

Promise 對(duì)象的錯(cuò)誤具有“冒泡”性質(zhì),會(huì)一直向后傳遞,直到被捕獲為止。也就是說,錯(cuò)誤總是會(huì)被下一個(gè)catch語句捕獲。

        getJSON("/post/1.json").then(function(post) {
          return getJSON(post.commentURL);
        }).then(function(comments) {
          // some code
        }).catch(function(error) {
          // 處理前面三個(gè)Promise產(chǎn)生的錯(cuò)誤
        });

catch方法返回的還是一個(gè) Promise 對(duì)象,因此后面還可以接著調(diào)用then方法。要是后續(xù)then方法里面報(bào)錯(cuò),就與前面的catch無關(guān)了。如果最后一個(gè)catch方法內(nèi)部拋出錯(cuò)誤,是無法捕獲的。為了避免潛在錯(cuò)誤,最好是在最后用一個(gè)catch方法兜底。

1.4 Promise.all():偏重狀態(tài)改變的邏輯與關(guān)系

用于將多個(gè)Promise實(shí)例包裝成一個(gè)新的Promise實(shí)例。如果內(nèi)部參數(shù)不是Promise實(shí)例,就調(diào)用Promise.resolve()將參數(shù)轉(zhuǎn)換為Promise實(shí)例。

        var p = Promise.all([p1, p2, p3]);//接受一個(gè)Promise數(shù)組作為參數(shù)

p的狀態(tài)由p1、p2、p3決定,呈現(xiàn)&關(guān)系,fulfilled對(duì)應(yīng)1,rejected對(duì)應(yīng)0,分成兩種情況:
(1)只有p1、p2、p3的狀態(tài)都變成fulfilled,p的狀態(tài)才會(huì)變成fulfilled,此時(shí)p1、p2、p3的返回值組成一個(gè)數(shù)組,傳遞給p的回調(diào)函數(shù)。
(2)只要p1、p2、p3之中有一個(gè)被rejected,p的狀態(tài)就變成rejected,此時(shí)第一個(gè)被reject的實(shí)例的返回值(rejected的順序有沒有類似與操作的順序?),會(huì)傳遞給p的回調(diào)函數(shù)。

        const databasePromise = connectDatabase();
        const booksPromise = databasePromise
          .then(findAllBooks);
        
        const userPromise = databasePromise
          .then(getCurrentUser);
        
        Promise.all([
          booksPromise,
          userPromise
        ])
        .then(([books, user]) => pickTopRecommentations(books, user));

上面代碼中,booksPromise和userPromise是兩個(gè)并行執(zhí)行的異步操作,只有等到它們的結(jié)果都返回了,才會(huì)觸發(fā)pickTopRecommentations這個(gè)回調(diào)函數(shù)。

1.5 Promise.race():偏重狀態(tài)改變的時(shí)間順序

Promise.race()和Promise.all()同樣是將多個(gè)Promise實(shí)例包裝成一個(gè)新的Promise實(shí)例,但是只要實(shí)例數(shù)組中有一個(gè)實(shí)例率先改變狀態(tài),p的狀態(tài)就跟著改變。那個(gè)率先改變的 Promise 實(shí)例的返回值,就傳遞給新實(shí)例的回調(diào)函數(shù)。

        var p = Promise.race([p1, p2, p3]);

Promise.race方法的參數(shù)與Promise.all方法一樣,如果不是 Promise 實(shí)例,就會(huì)先調(diào)用下面講到的Promise.resolve方法,將參數(shù)轉(zhuǎn)為 Promise 實(shí)例,再進(jìn)一步處理。

        const p = Promise.race([
          fetch("/resource-that-may-take-a-while"),
          new Promise(function (resolve, reject) {
            setTimeout(() => reject(new Error("request timeout")), 5000)
          })
        ]);
        p.then(response => console.log(response));
        p.catch(error => console.log(error));

上面代碼中,如果5秒之內(nèi)fetch方法無法返回結(jié)果,變量p的狀態(tài)就會(huì)變?yōu)閞ejected,從而觸發(fā)catch方法指定的回調(diào)函數(shù)。

1.6 Promise.resolve()

將現(xiàn)有對(duì)象轉(zhuǎn)化為Promise對(duì)象,根據(jù)參數(shù)不同有不同結(jié)果:
(1) 參數(shù)是一個(gè)Promise實(shí)例,Promise.resolve()將原對(duì)象返回;
(2) 參數(shù)是具有then方法的對(duì)象,Promise.resolve方法會(huì)將這個(gè)對(duì)象轉(zhuǎn)為Promise對(duì)象,然后就立即執(zhí)行thenable對(duì)象的then方法。

        let thenable = {
          then: function(resolve, reject) {
            resolve(42);
          }
        };
        
        let p1 = Promise.resolve(thenable);
        p1.then(function(value) {
          console.log(value);  // 42
        });

thenable對(duì)象的then方法執(zhí)行后,對(duì)象p1的狀態(tài)就變?yōu)閞esolved,從而立即執(zhí)行最后那個(gè)then方法指定的回調(diào)函數(shù),輸出42。

(3) 如果參數(shù)是一個(gè)原始值(基本類型值),或者是一個(gè)不具有then方法的對(duì)象,則Promise.resolve方法返回一個(gè)新的Promise對(duì)象,狀態(tài)為Resolved。

        var p = Promise.resolve("Hello");
        p.then(function (s){
          console.log(s)
        });
        // Hello

上面代碼生成一個(gè)新的Promise對(duì)象的實(shí)例p。由于字符串Hello不屬于異步操作(判斷方法是它不是具有then方法的對(duì)象),返回Promise實(shí)例的狀態(tài)從一生成就是Resolved,所以回調(diào)函數(shù)會(huì)立即執(zhí)行。Promise.resolve方法的參數(shù),會(huì)同時(shí)傳給回調(diào)函數(shù)。
(4) Promise.resolve方法允許調(diào)用時(shí)不帶參數(shù),直接返回一個(gè)Resolved狀態(tài)的Promise對(duì)象。所以,如果希望得到一個(gè)Promise對(duì)象,比較方便的方法就是直接調(diào)用Promise.resolve方法。

        var p = Promise.resolve();
        p.then(function () {
          // ...
        });

立即resolve的Promise對(duì)象,是在本輪“事件循環(huán)”(event loop)的結(jié)束時(shí),而不是在下一輪“事件循環(huán)”的開始時(shí),這個(gè)很好理解,通過resolve產(chǎn)生的Promise對(duì)象然后調(diào)用then函數(shù)和先產(chǎn)生Promise對(duì)象,對(duì)象轉(zhuǎn)換成resolved后再執(zhí)行then函數(shù)是一樣的,都是在本輪事件輪詢的末尾執(zhí)行。

        //下一輪事件輪詢開始
        setTimeout(function () {
          console.log("three");
        }, 0);
        //本輪事件輪詢末尾
        Promise.resolve().then(function () {
          console.log("two");
        });
        //立即執(zhí)行
        console.log("one");
        
        // one two three

上面代碼中,setTimeout(fn, 0)在下一輪“事件循環(huán)”開始時(shí)執(zhí)行,Promise.resolve()在本輪“事件循環(huán)”結(jié)束時(shí)執(zhí)行,console.log(’one‘)則是立即執(zhí)行,因此最先輸出。

1.7 Promise.reject()

Promise.reject()返回一個(gè)Promise實(shí)例,實(shí)例狀態(tài)為rejected。Promise.reject()方法的參數(shù),會(huì)原封不動(dòng)地作為reject的理由,變成后續(xù)方法的參數(shù)。這一點(diǎn)與Promise.resolve方法不一致。
實(shí)例1:

        var p = Promise.reject("出錯(cuò)了");
        // 等同于var p = new Promise((resolve, reject) => reject("出錯(cuò)了"))
        //參數(shù)就是’出錯(cuò)了’
        p.then(null, function (s) {
          console.log(s)
        });// 出錯(cuò)了

實(shí)例2:

        const thenable = {
          then(resolve, reject) {
            reject("出錯(cuò)了");
          }
        };
        //參數(shù)就是thenable
        Promise.reject(thenable)
        .catch(e => {
          console.log(e === thenable)
        })
        // true

上面代碼中,Promise.reject方法的參數(shù)是一個(gè)thenable對(duì)象,執(zhí)行以后,后面catch方法的參數(shù)不是reject拋出的“出錯(cuò)了”這個(gè)字符串,而是thenable對(duì)象。

2 加深Promise理解

Promises 給予我們的就是在我們使用異步Callback時(shí)丟失的最重要的語言基石: return, throw 以及堆棧。但是想要 promises 能夠提供這些便利給你的前提是你知道如何正確的使用它們。

2.1 使用Promise.resolve()創(chuàng)建Promise對(duì)象

任何有可能 throw 同步異常的代碼都是一個(gè)后續(xù)會(huì)導(dǎo)致幾乎無法調(diào)試異常的潛在因素。但是如果你將所有代碼都使用Promise.resolve() 封裝,那么你總是可以在之后使用 catch() 來捕獲它。因此方法2要優(yōu)于方法1。

方法1:

new Promise(function(resolve,reject){
    resolve(someSynchronousValue);
}).then(/*-------------*/);

方法2:

function somePromiseAPI() {
    return Promise.resolve().then(function(){
    doSomethinThatMayThrow();
    return ‘foo’;
}).then(/*------------*/);
}
2.2 catch() 與 then(null, ...) 根據(jù)使用場(chǎng)景并非完全等價(jià)

以下代碼等價(jià):

    somePromise().catch(function (err)){
    //handle error
    });
    //////////////////////////////////////
    somePromise().then(null, function(err)) {
    //handle error
    }

但是以下代碼不等價(jià):

    somePromise().then(function(){
        return someOtherPromise();
    }).catch(function(err){
        //error
    });
    ///////////////////////////////
    somePromise().then(function(){
        return someOtherPromise();
    },function(err){
        //error
    });

因此,當(dāng)你使用 then(resolveHandler, rejectHandler) 這種形式時(shí),rejectHandler 并不會(huì)捕獲由 resolveHandler 引發(fā)的異常。最好不使用then()的第二個(gè)參數(shù),而是總是使用catch(),唯一例外是寫一些異步的Mocha測(cè)試時(shí),使用then()的第二個(gè)參數(shù),希望拋出用例的異常。

2.3 promises vs promises factories

當(dāng)我們希望執(zhí)行一個(gè)個(gè)的執(zhí)行一個(gè) promises 序列,即類似 Promise.all() 但是并非并行的執(zhí)行所有 promises。你可能天真的寫下這樣的代碼:

        function executeSequentially(promise){
            var result = Promise.resolve();
            promises.forEach(function (promise)){
                result = result.then(promise);
            });
            return result;
        }

不幸的是,這份代碼不會(huì)按照你的期望去執(zhí)行,你傳入 executeSequentially() 的 promises 依然會(huì)并行執(zhí)行。其根源在于你所希望的,實(shí)際上根本不是去執(zhí)行一個(gè) promises 序列。依照 promises 規(guī)范,一旦一個(gè) promise 被創(chuàng)建,它就被執(zhí)行了。因此你實(shí)際上需要的是一個(gè) promise factories 數(shù)組。
我知道你在想什么:“這是哪個(gè)見鬼的 Java 程序猿,他為啥在說 factories?” 。實(shí)際上,一個(gè) promises factory 是十分簡(jiǎn)單的,它僅僅是一個(gè)可以返回 promise 的函數(shù):

        function executeSequentially(promiseFactories){
            var result = Promise.resolve();
            promiseFactories,forEach(function (promiseFactory){
            result = result.then(promiseFactory)
        });
        return result;
        }
        function promiseFactory(){
            return somethingThatCreatesAPromise();
        }

為何這樣就可以了?這是因?yàn)橐粋€(gè) promise factory 在被執(zhí)行之前并不會(huì)創(chuàng)建 promise。它就像一個(gè) then 函數(shù)一樣,而實(shí)際上,它們就是完全一樣的東西。如果你查看上面的 executeSequentially() 函數(shù),然后想象 myPromiseFactory 被包裹在 result.then(...) 之中,也許你腦中的小燈泡就會(huì)亮起。在此時(shí)此刻,對(duì)于 promise 你就算是悟道了。

2.4 promises 穿透
        Promise.resolve(‘foo’).then(Promise.resolve(‘bar’)).then(function(result){
        console.log(result);
        });

執(zhí)行結(jié)果并非是bar,而是foo,這是因?yàn)楫?dāng)then()接受非函數(shù)的參數(shù)時(shí),會(huì)解釋為then(null),這就導(dǎo)致前一個(gè)Promise的結(jié)果穿透到下面一個(gè)Promise。正確的寫法是在then()方法內(nèi)部包含函數(shù):

        Promise.resolve(‘foo’).then(function(){
        return Promise.resolve(‘bar’);
        }).then(function(result){
        console.log(result);
        });
2.5 Promise.all()

Promise.all()以一個(gè)Promise數(shù)組作為輸入,返回一個(gè)新的Promise,特點(diǎn)在于它會(huì)并行執(zhí)行數(shù)組中的每個(gè)Promise,并且每個(gè)Promise都返回后才返回結(jié)果數(shù)組,這就數(shù)組的異步版map/forEach方法。但是如果需要返回兩個(gè)不相關(guān)的結(jié)果,使用Promise.all()可以產(chǎn)生兩個(gè)不相關(guān)的數(shù)組結(jié)果;但是如果后一結(jié)果要依靠前一個(gè)結(jié)果產(chǎn)生,此時(shí)在Promise里使用嵌套也就可以的:

        getUserByName(‘bill’).then(function(user){
            return getUserAccountById(user.id);
        }).then(function (userAccount){
        /*-----------------*/
        });

或者在內(nèi)部使用嵌套:

        getUserByName(‘bill’).then(function(user){
                return getUserAccountById(user.id).then(function(userAccount){
                    /*--------------------*/
                });
        });

忘記使用catch:沒人可以保證不出錯(cuò),所以還是在最后加一個(gè)catch吧!

Q: 假定 doSomething() 和 doSomethingElse() 均返回 promises,下面的四種 promises 的區(qū)別是什么

        //1
        doSomething().then(function(){
            return doSomethingElse();
        }).then(finalHandler);
        // doSomething()返回一個(gè)Promise實(shí)例,但是后續(xù)的then方法里是一個(gè)匿名函數(shù),該函數(shù)產(chǎn)生一個(gè)新的Promise實(shí)例并返回這個(gè)實(shí)例,因此finalHandler的參數(shù)就是這個(gè)實(shí)例的resolve返回值。
        doSomething
        /-----------------/
                    doSomethingElse(undefined)
                    /----------------------------------/
                                            finalHandler(reulstOfDoSomethingElse)
                                            /--------------------------------------------------/
        //2
        doSomething().then(function(){
            doSomethingElse();
        }).then(finalHandler);
        //doSomething()返回一個(gè)Promise實(shí)例,但是后續(xù)的then方法里是一個(gè)匿名函數(shù),該函數(shù)產(chǎn)生一個(gè)新的Promise實(shí)例,但是由于這個(gè)函數(shù)沒有返回值,因此finalHandler函數(shù)沒有參數(shù)。
        doSomething
        /-----------------/
                    doSomethingElse(undefined)
                    /----------------------------------/
                    finalHandler(undefined)
                    /----------------------------------/
        
        //3
        doSomething().then(doSomethingElse())
        .then(finalHandler);
        // doSomething()返回一個(gè)Promise實(shí)例,但是后續(xù)的doSomethingElse()是一個(gè)立即執(zhí)行函數(shù),不接受上一Promise實(shí)例的resolve參數(shù),所以參數(shù)是undefined,這時(shí)doSomething()的Promise穿透到finalHandler,finalHandler的參數(shù)就是該P(yáng)romise的resolve參數(shù)。
        doSomething
        /-----------------/
        doSomethingElse(undefined)
        /----------------------------------/
                                finalHandler(reulstOfDoSomething)
                                /--------------------------------------------------/
        
        //4
        doSomething().then(doSomethingElse)
        .then(finalHandler);
        //doSomething()返回一個(gè)Promise實(shí)例,隨后調(diào)用doSomethingElse以上一實(shí)例的resolve參數(shù)產(chǎn)生第二個(gè)Promise,最后是finalHandler以上一實(shí)例的resolve參數(shù)產(chǎn)生第三個(gè)Promise。
        doSomething
        /-----------------/
                    doSomethingElse(resultOfDoSomething)
                    /----------------------------------/
                                            finalHandler(reulstOfDoSomethingElse)
                                            /--------------------------------------------------/

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/81867.html

相關(guān)文章

  • 需要知道的JS的日期知識(shí),都在這了

    摘要:實(shí)際上是格林威治標(biāo)準(zhǔn)時(shí)間的同義詞默認(rèn)情況下,中的幾乎每個(gè)日期方法除了一個(gè)都是本地時(shí)間。如果你住在格林威治標(biāo)準(zhǔn)時(shí)間晚的的地區(qū),你會(huì)得到一個(gè)日期是月日。需要知道對(duì)象日期方法。 為了保證的可讀性,本文采用意譯而非直譯。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! JS中的 Date 很奇怪。當(dāng)我們需要處理日期和時(shí)間的時(shí)候比較麻煩,經(jīng)常借助像date-fns和 Mom...

    testbird 評(píng)論0 收藏0
  • 你要的 React 面試知識(shí)點(diǎn),都在這了

    摘要:是流行的框架之一,在年及以后將會(huì)更加流行。于年首次發(fā)布,多年來廣受歡迎。下面是另一個(gè)名為的高階函數(shù)示例,該函數(shù)接受另外兩個(gè)函數(shù),分別是和。將所有較小的函數(shù)組合成更大的函數(shù),最終,得到一個(gè)應(yīng)用程序,這稱為組合。 React是流行的javascript框架之一,在2019年及以后將會(huì)更加流行。React于2013年首次發(fā)布,多年來廣受歡迎。它是一個(gè)聲明性的、基于組件的、用于構(gòu)建用戶界面的高...

    klinson 評(píng)論0 收藏0
  • 零基礎(chǔ) | 入行軟件測(cè)試,你想知道的在這里了

    摘要:應(yīng)屆生零基礎(chǔ)可以學(xué)習(xí)軟件測(cè)試嗎俗話說,人怕入錯(cuò)行。霸哥這里分別從入行難度入行方式行業(yè)前景薪資待遇四個(gè)方面來分析一下。目前市場(chǎng)上的測(cè)試人員,一部分是企業(yè)自己培養(yǎng)的,另一部分是來自培訓(xùn)機(jī)構(gòu)。軟件測(cè)試的行業(yè)門檻低,市場(chǎng)需求量大。 ...

    neroneroffy 評(píng)論0 收藏0
  • 前端進(jìn)階系列-目錄

    摘要:然而在最近的面試中通過學(xué)習(xí)和思考,找到了前進(jìn)的方向,也得到一些大公司的錄用機(jī)會(huì)。算是從初級(jí)前端畢業(yè),進(jìn)階了吧。在這里先寫個(gè)目錄。趕時(shí)間的同學(xué)可以按照我的目錄先自行準(zhǔn)備提升,希望推薦文章和交流。 背景 之前我分享了文章大廠前端面試考什么?,你們一定很想看答案吧?說實(shí)話,答案我是有,在準(zhǔn)備面試的時(shí)候會(huì)時(shí)不時(shí)翻看,但內(nèi)容比較多,比較凌亂,不能指望我在一篇文章中寫完。 我是從非計(jì)算機(jī)專業(yè)自學(xué)前...

    cod7ce 評(píng)論0 收藏0
  • 編寫一個(gè)并發(fā)性能測(cè)試的小程序

    摘要:并發(fā)線程測(cè)試循環(huán)新建線程類,并在線程體內(nèi)塞入單個(gè)的測(cè)試用例,以及全局的計(jì)數(shù)類。為了讓性能測(cè)試更充分,我編寫了不同的計(jì)算過程,并使用隨機(jī)函數(shù)隨機(jī)獲取并塞入線程執(zhí)行。 ...

    Michael_Lin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<