国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

node.js下when.js 的異步編程實踐

2024-05-06 16:11:20
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了node.js下when.js 的異步編程實踐,需要的朋友可以參考下
 
 

假設一個業務場景:

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

完成該場景的業務需要完成3個任務:

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

2.獲取rss。

3.保存于文件。

最后將這三個任務進行整合。

準備:

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

http://programmer.csdn.net/rss_programmer.html
 
任務1:

讀取rss地址文件的內容并通過callback返回。

 

復制代碼代碼如下:

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

 

任務2:

 通過rss地址get到rss,并通過callback返回錯誤或數據。

 

復制代碼代碼如下:

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);
  });
}

 

 

任務3:

將rss保存于文件并通過callback返回錯誤。

 

復制代碼代碼如下:

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

 

整合:

 

復制代碼代碼如下:

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);
    });
  });
});

 

上面的代碼是全異步處理,使用最常見的callback處理異步邏輯的返回,好處是標準寫法,大家都能容易接受;壞處是耦合性太強,處理異常麻煩,代碼不直觀,特別是處理業務邏輯復雜和處理任務多的場景,層層的callback會讓人眼冒金星,代碼難以維護。

Promise/A規范的實現之一when.js正是針對這樣的問題域。

讓我們來看一下改造后的代碼。

任務1:

 

復制代碼代碼如下:

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;
}


 
任務2:

 

 

復制代碼代碼如下:

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;
}

 

任務3:

 

復制代碼代碼如下:

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;
}


 

 

整合:

 

復制代碼代碼如下:

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

 

解釋:

promise/A規范定義的“Deferred/Promise”模型就是“發布/訂閱者”模型,通過Deferred對象發布事件,可以是完成resolve事件,或者是失敗reject事件;通過Promise對象進行對應完成或失敗的訂閱。

在Promises/A規范中,每個任務都有三種狀態:默認(pending)、完成(fulfilled)、失敗(rejected)。

1.默認狀態可以單向轉移到完成狀態,這個過程叫resolve,對應的方法是deferred.resolve(promiseOrValue);

2.默認狀態還可以單向轉移到失敗狀態,這個過程叫reject,對應的方法是deferred.reject(reason);

3.默認狀態時,還可以通過deferred.notify(update)來宣告任務執行信息,如執行進度;

4.狀態的轉移是一次性的,一旦任務由初始的pending轉為其他狀態,就會進入到下一個任務的執行過程中。

按照上面的代碼。

通過when.defer定義一個deferred對象。

var deferred = when.defer();
異步數據獲取成功后,發布一個完成事件。

deferred.resolve(data);
異步數據獲取失敗后,發布一個失敗事件。

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

return deferred.promise;
訂閱是通過Promise對象的then方法進行完成/失敗/通知的訂閱。

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

promise.then(onFulfilled, onRejected, onProgress)
上一個任務被resolve(data),onFulfilled函數就會被觸發,data作為它的參數.

上一個任務被reject(reason),那么onRejected就會被觸發,收到reason。

任何時候,onFulfilled和onRejected都只有其一可以被觸發,并且只觸發一次。

對于處理異常,when.js也提供了極其方便的方法,then能傳遞錯誤,多個任務串行執行時,我們可以只在最后一個then定義onRejected。也可以在最后一個then的后面調用catch函數捕獲任何一個任務的異常。

如此寫法簡單明了。

 

復制代碼代碼如下:

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

 

Promise給異步編程帶來了巨大的方便,可以讓我們專注于單個任務的實現而不會陷入金字塔厄運,以上代碼僅僅是基本使用,when.js提供的功能遠遠不止本文提到的這些,具體參照官方API。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 肥城市| 洮南市| 长沙县| 民丰县| 寻乌县| 兴山县| 穆棱市| 河间市| 通榆县| 兴国县| 兴和县| 西和县| 吉安市| 万年县| 邻水| 肥东县| 海口市| 彰化县| 宜州市| 惠安县| 玉林市| 旬邑县| 大足县| 兴山县| 当涂县| 宝鸡市| 洪湖市| 银川市| 从化市| 溧水县| 偃师市| 沅江市| 叙永县| 登封市| 涡阳县| 南昌市| 澄迈县| 巴中市| 沂水县| 大理市| 旬邑县|