亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

NodeJS中利用Promise來(lái)封裝異步函數(shù)

 更新時(shí)間:2015年02月25日 15:11:48   投稿:hebedich  
這篇文章主要介紹了NodeJS中利用Promise來(lái)封裝異步函數(shù),使用統(tǒng)一的鏈?zhǔn)紸PI來(lái)擺脫多重回調(diào)的噩夢(mèng),非常的實(shí)用的小技能,希望小伙伴們能夠喜歡

 在寫(xiě)Node.js的過(guò)程中,連續(xù)的IO操作可能會(huì)導(dǎo)致“金字塔噩夢(mèng)”,回調(diào)函數(shù)的多重嵌套讓代碼變的難以維護(hù),利用CommonJs的Promise來(lái)封裝異步函數(shù),使用統(tǒng)一的鏈?zhǔn)紸PI來(lái)擺脫多重回調(diào)的噩夢(mèng)。

  Node.js提供的非阻塞IO模型允許我們利用回調(diào)函數(shù)的方式處理IO操作,但是當(dāng)需要連續(xù)的IO操作時(shí),你的回調(diào)函數(shù)會(huì)多重嵌套,代碼很不美觀,而且不易維護(hù),而且可能會(huì)有許多錯(cuò)誤處理的重復(fù)代碼,也就是所謂的“Pyramid of Doom”。

復(fù)制代碼 代碼如下:

step1(function (value1) {
    step2(value1, function(value2) {
        step3(value2, function(value3) {
            step4(value3, function(value4) {
                // Do something with value4
            });
        });
    });
});

  這其實(shí)就是Node.js的Control flow的問(wèn)題,對(duì)于這個(gè)問(wèn)題,解決方案都許多,比如利用async,或者eventProxy等,不過(guò)本文的主題是利用CommonJs規(guī)范中對(duì)Promise來(lái)解決這個(gè)問(wèn)題。

什么是Promise?

  CommonJs的Promise規(guī)范有許多種,我們一般討論的是Promise/A+規(guī)范,它定義了Promise的基本行為。

  Promise是一個(gè)對(duì)象,它通常代表一個(gè)在未來(lái)可能完成的異步操作。這個(gè)操作可能成功也可能失敗,所以一個(gè)Promise對(duì)象一般有3個(gè)狀態(tài):Pending,F(xiàn)ulfilled,Rejected。分別代表未完成、成功完成和操作失敗。一旦Promise對(duì)象的狀態(tài)從Pending變成Fulfilled或者Rejected任意一個(gè),它的狀態(tài)都沒(méi)有辦法再被改變。

  一個(gè)Promise對(duì)象通常會(huì)有一個(gè)then方法,這個(gè)方法讓我們可以去操作未來(lái)可能成功后返回的值或者是失敗的原因。這個(gè)then方法是這樣子的:

promise.then(onFulfilled, onRejected)
  顯而易見(jiàn)的是,then方法接受兩個(gè)參數(shù),它們通常是兩個(gè)函數(shù),一個(gè)是用來(lái)處理操作成功后的結(jié)果的,另一個(gè)是用來(lái)處理操作失敗后的原因的,這兩個(gè)函數(shù)的第一個(gè)參數(shù)分別是成功后的結(jié)果和失敗的原因。如果傳給then方法的不是一個(gè)函數(shù),那么這個(gè)參數(shù)會(huì)被忽略。

  then方法的返回值是一個(gè)Promise對(duì)象,這一個(gè)特點(diǎn)允許我們鏈?zhǔn)秸{(diào)用then來(lái)達(dá)到控制流程的效果。這里有許多細(xì)節(jié)上的問(wèn)題,比如值的傳遞或者錯(cuò)誤處理等。Promise的規(guī)范是這樣定義的:

onFulfilled或者onRejected函數(shù)的返回值不是Promise對(duì)象,則該值將會(huì)作為下一個(gè)then方法中onFulfilled的第一個(gè)參數(shù),如果返回值是一個(gè)Promise對(duì)象,怎么then方法的返回值就是該P(yáng)romise對(duì)象
onFulfilled或者onRejected函數(shù)中如果有異常拋出,則該then方法的返回的Promise對(duì)象狀態(tài)轉(zhuǎn)為Rejected,如果該P(yáng)romise對(duì)象調(diào)用then,則Error對(duì)象會(huì)作為onRejected函數(shù)的第一個(gè)參數(shù)
如果Promise狀態(tài)變?yōu)镕ulfilled而在then方法中沒(méi)有提供onFulfilled函數(shù),則then方法返回的Promise對(duì)象狀態(tài)變?yōu)镕ulfilled且成功的結(jié)果為上一個(gè)Promise的結(jié)果,Rejected同理。
  補(bǔ)充一句,onFulfilled和onRejected都是異步執(zhí)行的。

規(guī)范的實(shí)現(xiàn):q

  上面講的是Promise的規(guī)范,而我們需要的是它的實(shí)現(xiàn),q是一個(gè)對(duì)Promise/A+有著較好實(shí)現(xiàn)規(guī)范的庫(kù)。

  首先我們需要?jiǎng)?chuàng)建一個(gè)Promise對(duì)象,關(guān)于Promise對(duì)象創(chuàng)建的規(guī)范在Promise/B中,這里不做詳細(xì)的解釋?zhuān)苯由洗a。

復(fù)制代碼 代碼如下:

    function(flag){
        var defer = q.defer();
        fs.readFile("a.txt", function(err, data){
        if(err) defer.reject(err);
            else defer.resolve(data);
            });
            return defer.promise;
    }

  多數(shù)Promise的實(shí)現(xiàn)在Promise的創(chuàng)建上大同小異,通過(guò)創(chuàng)建一個(gè)具有promise屬性的defer對(duì)象,如果成功獲取到值則調(diào)用defer.resolve(value),如果失敗,則調(diào)用defer.reject(reason),最后返回defer的promise屬性即可。這個(gè)過(guò)程可以理解為調(diào)用defer.resolve將Promise的狀態(tài)變成Fulfilled,調(diào)用defer.reject將Promise的狀態(tài)變成Rejected。

  在面對(duì)一系列連續(xù)的異步方法時(shí),怎么利用Promise寫(xiě)出漂亮的代碼呢?看下下面的例子。

復(fù)制代碼 代碼如下:

    promise0.then(function(result){
        // dosomething
        return result;
    }).then(function(result) {
        // dosomething
        return promise1;   
    }).then(function(result) {
        // dosomething
    }).catch(function(ex) {
        console.log(ex);
    }).finally(function(){
        console.log("final");
    });

  在上面的代碼中,then方法只接受OnFulfilled,而catch方法實(shí)際上就是then(null, OnRejected),這樣的話只要一系列異步方法只要始終是成功返回值的,那么代碼就會(huì)瀑布式的向下運(yùn)行,如果其中任意一個(gè)異步方法失敗或者發(fā)生異常,那么根據(jù)CommonJs的Promise規(guī)范,將執(zhí)行catch中的function。q還提供了finally方法,從字面上也很好理解,就是不論resolve還是reject,最終都會(huì)執(zhí)行finally中的function。

  看上去似乎不錯(cuò),代碼更以維護(hù)且美觀了,那么如果希望并發(fā)呢?

復(fù)制代碼 代碼如下:

     q.all([promise0, promise1, promise2]).spread(function(val0, val1, val2){
                    console.log(arguments);
                }).then(function(){
                    console.log("done");
                }).catch(function(err){
                    console.log(err);
                });

  q也為并發(fā)提供了api,調(diào)用all方法并傳遞一個(gè)Promise數(shù)組即可繼續(xù)使用then的鏈?zhǔn)斤L(fēng)格。還有像q.nfbind等可以將Node.js的原生API轉(zhuǎn)化成Promise來(lái)統(tǒng)一代碼格式也是挺好的。更多api在這里就不一一詳述了。

結(jié)論

  本文主要介紹通過(guò)使用Promise來(lái)解決Node.js控制流問(wèn)題,但Promise也可同樣應(yīng)用于前端,EMCAScript6已經(jīng)提供了原生的API支持。需要指出的是Promise并不是唯一的解決方案,async也是一個(gè)很好的選擇,并且提供更友好的并發(fā)控制API,不過(guò)我覺(jué)得Promise在封裝具有異步方法的函數(shù)時(shí)更具優(yōu)勢(shì)。

好了,本文就先到這里了,希望對(duì)大家能夠有所幫助。

相關(guān)文章

  • Node.js中的process.nextTick使用實(shí)例

    Node.js中的process.nextTick使用實(shí)例

    這篇文章主要介紹了Node.js中的process.nextTick使用實(shí)例,nextTick函數(shù)有什么用、怎么用、和setTimeout有什么區(qū)別呢,本文就講解了這些知識(shí),需要的朋友可以參考下
    2015-06-06
  • 使用nvm和nrm優(yōu)化node.js工作流的方法

    使用nvm和nrm優(yōu)化node.js工作流的方法

    這篇文章主要介紹了使用nvm和nrm優(yōu)化node.js工作流的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • Nodejs 和Session 原理及實(shí)戰(zhàn)技巧小結(jié)

    Nodejs 和Session 原理及實(shí)戰(zhàn)技巧小結(jié)

    這篇文章主要介紹了Nodejs 和Session 原理及實(shí)戰(zhàn)技巧小結(jié),需要的朋友可以參考下
    2017-08-08
  • koa socket即時(shí)通訊的示例代碼

    koa socket即時(shí)通訊的示例代碼

    這篇文章主要介紹了koa socket即時(shí)通訊的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • Windows 系統(tǒng)下安裝和部署Egret的開(kāi)發(fā)環(huán)境

    Windows 系統(tǒng)下安裝和部署Egret的開(kāi)發(fā)環(huán)境

    Egret基于TypeScript開(kāi)發(fā)的,而TypeScript編譯工具tsc是基于Node.js 開(kāi)發(fā)的。所以在安裝過(guò)程中,我們先需要對(duì)于基礎(chǔ)支持工具進(jìn)行安裝。
    2014-07-07
  • Node快速切換版本、版本回退(降級(jí))、版本更新(升級(jí))

    Node快速切換版本、版本回退(降級(jí))、版本更新(升級(jí))

    這篇文章主要介紹了Node快速切換版本、版本回退(降級(jí))、版本更新(升級(jí)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • nodejs動(dòng)態(tài)創(chuàng)建二維碼的方法

    nodejs動(dòng)態(tài)創(chuàng)建二維碼的方法

    這篇文章主要為大家詳細(xì)介紹了nodejs動(dòng)態(tài)創(chuàng)建二維碼的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • express如何使用session與cookie的方法

    express如何使用session與cookie的方法

    本篇文章主要介紹了express如何使用session與cookie的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • 基于Node.js的http模塊搭建HTTP服務(wù)器

    基于Node.js的http模塊搭建HTTP服務(wù)器

    這篇文章主要為大家介紹了基于Node.js的http模塊來(lái)搭建HTTP服務(wù)器的示例過(guò)程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • node.js安裝及HbuilderX配置詳解

    node.js安裝及HbuilderX配置詳解

    這篇文章主要介紹了node.js安裝及HbuilderX配置的相關(guān)資料,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03

最新評(píng)論