欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

node.js下when.js 的異步編程實(shí)踐

 更新時(shí)間:2014年12月03日 11:35:34   投稿:hebedich  
這篇文章主要介紹了node.js下when.js 的異步編程實(shí)踐,需要的朋友可以參考下

假設(shè)一個(gè)業(yè)務(wù)場(chǎng)景:

通過(guò)rss地址,獲取rss并保存于文件,rss地址保存于文件中。

完成該場(chǎng)景的業(yè)務(wù)需要完成3個(gè)任務(wù):

1.從文件中讀取rss地址。

2.獲取rss。

3.保存于文件。

最后將這三個(gè)任務(wù)進(jìn)行整合。

準(zhǔn)備:

存放rss地址的文件,address.txt。

http://programmer.csdn.net/rss_programmer.html
 
任務(wù)1:

讀取rss地址文件的內(nèi)容并通過(guò)callback返回。

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

var getRssAddress = function(path, callback) {
  fs.readFile(path, {encoding: 'utf8'}, function (err, data) {
    callback(err, data);
  });
}

任務(wù)2:

 通過(guò)rss地址get到rss,并通過(guò)callback返回錯(cuò)誤或數(shù)據(jù)。

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

var getRss = function(url, callback) {
  var data = '';
  http.get(url, function(res) {
    res.on('data', function(chrunk) {
      data += chrunk;
    });
    res.on('end', function() {
      callback(null, data);
    });
  }).on('error', function(err) {
    callback(err, null);
  });
}

 

任務(wù)3:

將rss保存于文件并通過(guò)callback返回錯(cuò)誤。

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

var saveRss = function(data, callback) {
  fs.writeFile('rss.txt', data, 'utf8', function(err) {
    callback(err);
  });
}

整合:

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

getRssAddress('address.txt', function(err, data) {
  if(err) {
    console.log(err);
    return;
  }
  getRss(data, function(err, data) {
    if(err) {
      console.log(err);
      return;
    }
    saveRss(data, function(err) {
      if(err) console.log(err);
    });
  });
});

上面的代碼是全異步處理,使用最常見(jiàn)的callback處理異步邏輯的返回,好處是標(biāo)準(zhǔn)寫(xiě)法,大家都能容易接受;壞處是耦合性太強(qiáng),處理異常麻煩,代碼不直觀,特別是處理業(yè)務(wù)邏輯復(fù)雜和處理任務(wù)多的場(chǎng)景,層層的callback會(huì)讓人眼冒金星,代碼難以維護(hù)。

Promise/A規(guī)范的實(shí)現(xiàn)之一when.js正是針對(duì)這樣的問(wèn)題域。

讓我們來(lái)看一下改造后的代碼。

任務(wù)1:

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

var getRssAddress = function(path) {
    var deferred = when.defer();
      fs.readFile(path, {encoding: 'utf8'}, function (err, data) {
        if (err) deferred.reject(err);
        deferred.resolve(data);
      });

    return deferred.promise;
}


 
任務(wù)2:

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

var getRss = function(url) {
  var deferred = when.defer();
    var data = '';
    http.get(url, function(res) {
      res.on('data', function(chrunk) {
        data += chrunk;
      });
      res.on('end', function() {
        deferred.resolve(data);
      });
    }).on('error', function(err) {
      deferred.reject(err);
    });

    return deferred.promise;
}

任務(wù)3:

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

var saveRss = function(data) {
  var deferred = when.defer();
  fs.writeFile('rss.txt', data, 'utf8', function(err) {
    if(err) deferred.reject(err);
    deferred.resolve();
  });

  return deferred.promise;
}


 

整合:

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

getRssAddress('address.txt')
  .then(getRss)
  .then(saveRss)
  .catch(function(err) {
    console.log(err);
  });

解釋?zhuān)?/p>

promise/A規(guī)范定義的“Deferred/Promise”模型就是“發(fā)布/訂閱者”模型,通過(guò)Deferred對(duì)象發(fā)布事件,可以是完成resolve事件,或者是失敗reject事件;通過(guò)Promise對(duì)象進(jìn)行對(duì)應(yīng)完成或失敗的訂閱。

在Promises/A規(guī)范中,每個(gè)任務(wù)都有三種狀態(tài):默認(rèn)(pending)、完成(fulfilled)、失敗(rejected)。

1.默認(rèn)狀態(tài)可以單向轉(zhuǎn)移到完成狀態(tài),這個(gè)過(guò)程叫resolve,對(duì)應(yīng)的方法是deferred.resolve(promiseOrValue);

2.默認(rèn)狀態(tài)還可以單向轉(zhuǎn)移到失敗狀態(tài),這個(gè)過(guò)程叫reject,對(duì)應(yīng)的方法是deferred.reject(reason);

3.默認(rèn)狀態(tài)時(shí),還可以通過(guò)deferred.notify(update)來(lái)宣告任務(wù)執(zhí)行信息,如執(zhí)行進(jìn)度;

4.狀態(tài)的轉(zhuǎn)移是一次性的,一旦任務(wù)由初始的pending轉(zhuǎn)為其他狀態(tài),就會(huì)進(jìn)入到下一個(gè)任務(wù)的執(zhí)行過(guò)程中。

按照上面的代碼。

通過(guò)when.defer定義一個(gè)deferred對(duì)象。

var deferred = when.defer();
異步數(shù)據(jù)獲取成功后,發(fā)布一個(gè)完成事件。

deferred.resolve(data);
異步數(shù)據(jù)獲取失敗后,發(fā)布一個(gè)失敗事件。

deferred.reject(err);
并且返回Promise對(duì)象作為訂閱使用。

return deferred.promise;
訂閱是通過(guò)Promise對(duì)象的then方法進(jìn)行完成/失敗/通知的訂閱。

getRssAddress('address.txt')
  .then(getRss)
then有三個(gè)參數(shù),分別是onFulfilled、onRejected、onProgress

promise.then(onFulfilled, onRejected, onProgress)
上一個(gè)任務(wù)被resolve(data),onFulfilled函數(shù)就會(huì)被觸發(fā),data作為它的參數(shù).

上一個(gè)任務(wù)被reject(reason),那么onRejected就會(huì)被觸發(fā),收到reason。

任何時(shí)候,onFulfilled和onRejected都只有其一可以被觸發(fā),并且只觸發(fā)一次。

對(duì)于處理異常,when.js也提供了極其方便的方法,then能傳遞錯(cuò)誤,多個(gè)任務(wù)串行執(zhí)行時(shí),我們可以只在最后一個(gè)then定義onRejected。也可以在最后一個(gè)then的后面調(diào)用catch函數(shù)捕獲任何一個(gè)任務(wù)的異常。

如此寫(xiě)法簡(jiǎn)單明了。

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

getRssAddress('address.txt')
  .then(getRss)
  .then(saveRss)
  .catch(function(err) {
    console.log(err);
  });

Promise給異步編程帶來(lái)了巨大的方便,可以讓我們專(zhuān)注于單個(gè)任務(wù)的實(shí)現(xiàn)而不會(huì)陷入金字塔厄運(yùn),以上代碼僅僅是基本使用,when.js提供的功能遠(yuǎn)遠(yuǎn)不止本文提到的這些,具體參照官方API。

相關(guān)文章

  • Node.js處理多個(gè)請(qǐng)求的技巧和方法

    Node.js處理多個(gè)請(qǐng)求的技巧和方法

    Node.js在處理多個(gè)請(qǐng)求方面具有優(yōu)勢(shì),它利用事件驅(qū)動(dòng)和非阻塞式I/O的特性,能夠高效地處理并發(fā)請(qǐng)求,提供快速響應(yīng)和良好的可擴(kuò)展性,這篇文章主要介紹了Node.js如何處理多個(gè)請(qǐng)求,需要的朋友可以參考下
    2023-11-11
  • nodeJS模塊簡(jiǎn)單用法示例

    nodeJS模塊簡(jiǎn)單用法示例

    這篇文章主要介紹了nodeJS模塊簡(jiǎn)單用法,結(jié)合實(shí)例形式簡(jiǎn)單分析了nodejs模塊定義、引入、注冊(cè)、啟動(dòng)等相關(guān)操作技巧,需要的朋友可以參考下
    2018-04-04
  • 詳解如何在NodeJS應(yīng)用程序中處理多個(gè)API請(qǐng)求

    詳解如何在NodeJS應(yīng)用程序中處理多個(gè)API請(qǐng)求

    NodeJS默認(rèn)是異步的,這意味著它已經(jīng)能夠同時(shí)處理多個(gè)請(qǐng)求,但它只適用于I/O操作,如HTTP請(qǐng)求、文件系統(tǒng)操作、數(shù)據(jù)庫(kù)查詢(xún)、實(shí)時(shí)聊天應(yīng)用等,在處理CPU密集型任務(wù)時(shí),可能需要很長(zhǎng)時(shí)間,這就是為什么NodeJS提供了一些我們將在下面介紹的特定包
    2023-12-12
  • Nodejs學(xué)習(xí)筆記之NET模塊

    Nodejs學(xué)習(xí)筆記之NET模塊

    之前兩篇文章基本上都是給我們介紹的nodejs的理論基礎(chǔ),今天我們來(lái)點(diǎn)干貨,先從NET模塊開(kāi)始講起吧。
    2015-01-01
  • 詳解如何使用nvm管理Node.js多版本

    詳解如何使用nvm管理Node.js多版本

    這篇文章主要介紹了詳解如何使用nvm管理Node.js多版本,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-05-05
  • 輕松創(chuàng)建nodejs服務(wù)器(5):事件處理程序

    輕松創(chuàng)建nodejs服務(wù)器(5):事件處理程序

    這篇文章主要介紹了輕松創(chuàng)建nodejs服務(wù)器(5):事件處理程序,本系列文章將一步一步創(chuàng)建一個(gè)完整的nodejs服務(wù)器,需要的朋友可以參考下
    2014-12-12
  • nodejs使用PassThrough流進(jìn)行數(shù)據(jù)傳遞合并示例詳解

    nodejs使用PassThrough流進(jìn)行數(shù)據(jù)傳遞合并示例詳解

    這篇文章主要為大家介紹了nodejs使用PassThrough流進(jìn)行數(shù)據(jù)傳遞合并示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • express中static中間件的具體使用方法

    express中static中間件的具體使用方法

    這篇文章主要介紹了express中static中間件的具體使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • nodejs接入阿里大魚(yú)短信驗(yàn)證碼的方法

    nodejs接入阿里大魚(yú)短信驗(yàn)證碼的方法

    本篇文章主要介紹了nodejs接入阿里大魚(yú)短信驗(yàn)證碼的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-07-07
  • Nodejs調(diào)用Dll模塊的方法

    Nodejs調(diào)用Dll模塊的方法

    這篇文章主要介紹了Nodejs調(diào)用Dll模塊的方法,在文中給大家提到了nodejs通過(guò)ffi調(diào)用dll模塊的代碼,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-09-09

最新評(píng)論