最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

 在寫Node.js的過程中,連續(xù)的IO操作可能會導致“金字塔噩夢”,回調(diào)函數(shù)的多重嵌套讓代碼變的難以維護,利用CommonJs的Promise來封裝異步函數(shù),使用統(tǒng)一的鏈式API來擺脫多重回調(diào)的噩夢。

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

復制代碼 代碼如下:

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

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

什么是Promise?

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

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

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

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

  then方法的返回值是一個Promise對象,這一個特點允許我們鏈式調(diào)用then來達到控制流程的效果。這里有許多細節(jié)上的問題,比如值的傳遞或者錯誤處理等。Promise的規(guī)范是這樣定義的:

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

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

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

  首先我們需要創(chuàng)建一個Promise對象,關(guān)于Promise對象創(chuàng)建的規(guī)范在Promise/B中,這里不做詳細的解釋,直接上代碼。

復制代碼 代碼如下:

    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的實現(xiàn)在Promise的創(chuàng)建上大同小異,通過創(chuàng)建一個具有promise屬性的defer對象,如果成功獲取到值則調(diào)用defer.resolve(value),如果失敗,則調(diào)用defer.reject(reason),最后返回defer的promise屬性即可。這個過程可以理解為調(diào)用defer.resolve將Promise的狀態(tài)變成Fulfilled,調(diào)用defer.reject將Promise的狀態(tài)變成Rejected。

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

復制代碼 代碼如下:

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

  看上去似乎不錯,代碼更以維護且美觀了,那么如果希望并發(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方法并傳遞一個Promise數(shù)組即可繼續(xù)使用then的鏈式風格。還有像q.nfbind等可以將Node.js的原生API轉(zhuǎn)化成Promise來統(tǒng)一代碼格式也是挺好的。更多api在這里就不一一詳述了。

結(jié)論

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

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

相關(guān)文章

  • Nodejs訪問網(wǎng)絡并解析返回的json的實現(xiàn)方法

    Nodejs訪問網(wǎng)絡并解析返回的json的實現(xiàn)方法

    本文主要介紹了Nodejs訪問網(wǎng)絡并解析返回的json的實現(xiàn)方法,文中根據(jù)實例編碼詳細介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 如何在Nestjs和Vue3中使用socket.io示例詳解

    如何在Nestjs和Vue3中使用socket.io示例詳解

    這篇文章主要為大家介紹了如何在Nestjs和Vue3中使用socket.io示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • window系統(tǒng)管理多版本node的實現(xiàn)

    window系統(tǒng)管理多版本node的實現(xiàn)

    存在不同項目使用npm時所需要的版本不一致,又不想每次都卸載又重新安裝node,這時候就需要多版本管理器,本文主要介紹了window系統(tǒng)管理多版本node的實現(xiàn),感興趣的可以了解一下
    2024-02-02
  • Nodejs使用SQL模糊查詢的過程詳解

    Nodejs使用SQL模糊查詢的過程詳解

    最近在改一個比較久的項目,是使用nodejs寫的,但是對于長期寫java的后端開發(fā)來說,還是有點難維護,不過不改bug的話,就需要重新開發(fā),所以本文介紹了NodeJs如何使用SQL模糊查詢,需要的朋友可以參考下
    2024-07-07
  • Nodejs實現(xiàn)爬蟲抓取數(shù)據(jù)實例解析

    Nodejs實現(xiàn)爬蟲抓取數(shù)據(jù)實例解析

    這篇文章主要介紹了Nodejs實現(xiàn)爬蟲抓取數(shù)據(jù)實例解析,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友參考下吧
    2018-07-07
  • sharp.js安裝過程中遇到的問題總結(jié)

    sharp.js安裝過程中遇到的問題總結(jié)

    本文給大家講述的是Node.js服務端圖片處理利器sharp.js安裝過程中遇到的問題的匯總,非常不錯,有需要的小伙伴可以參考下
    2020-04-04
  • 利用node.js爬取指定排名網(wǎng)站的JS引用庫詳解

    利用node.js爬取指定排名網(wǎng)站的JS引用庫詳解

    最近在學習node.js爬蟲,由于 nodejs 強大的異步特性,讓我們可以輕松以異步高并發(fā)去爬取網(wǎng)站,下面這篇文章主要給大家介紹了關(guān)于利用node.js爬取指定排名網(wǎng)站的JS引用庫的相關(guān)資料,需要的朋友可以參考下。
    2017-07-07
  • 詳解NodeJS Https HSM雙向認證實現(xiàn)

    詳解NodeJS Https HSM雙向認證實現(xiàn)

    這篇文章主要介紹了詳解NodeJS Https HSM雙向認證實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • node中的__filename和__dirname的使用詳解

    node中的__filename和__dirname的使用詳解

    本文主要介紹了node中的__filename和__dirname的使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • nodejs 遞歸拷貝、讀取目錄下所有文件和目錄

    nodejs 遞歸拷貝、讀取目錄下所有文件和目錄

    這篇文章主要介紹了nodejs 遞歸拷貝、讀取目錄下所有文件和目錄,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-07-07

最新評論

丰顺县| 皮山县| 安平县| 元谋县| 肃北| 黄大仙区| 绥中县| 广宗县| 察隅县| 轮台县| 诏安县| 宁晋县| 古田县| 三穗县| 游戏| 平原县| 玉龙| 翁牛特旗| 东兰县| 三都| 沛县| 金湖县| 荆门市| 禹城市| 新密市| 松溪县| 章丘市| 宜城市| 进贤县| 响水县| 张家口市| 读书| 竹溪县| 甘泉县| 望城县| 贞丰县| 云和县| 宁城县| 大英县| 汉沽区| 文登市|