亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

JavaScript異步編程:異步數據收集的具體方法

2019-11-20 22:23:22
字體:
來源:轉載
供稿:網友

Asyncjs/seriesByHand.js

復制代碼 代碼如下:

var fs = require('fs');
process.chdir('recipes'); // 改變工作目錄
var concatenation = '';

fs.readdir('.', function(err, filenames) {
  if (err) throw err;

  function readFileAt(i) {
    var filename = filenames[i];
    fs.stat(filename, function(err, stats) {
      if (err) throw err;
      if (! stats.isFile()) return readFileAt(i + 1);

      fs.readFile(filename, 'utf8', function(err, text) {
        if (err) throw err;
        concatenation += text;
        if (i + 1 === filenames.length) {
          // 所有文件均已讀取,可顯示輸出
          return console.log(concatenation);
        }
        readFileAt(i + 1);
      });
    });
  }
  readFileAt(0);
});

如你所見,異步版本的代碼要比同步版本多很多。如果使用filter、forEach這些同步方法,代碼的行數大約只有一半,而且讀起來也要容易得多。如果這些漂亮的迭代器存在異步版本該多好啊!使用Async.js就能做到這一點!

 

何時拋出亦無妨?

大家可能注意到了,在上面那個代碼示例中筆者無視了自己在第1.4節中提出的建議:從回調里拋出異常是一種糟糕的設計,尤其在成品環境中。不過,一個簡單如斯的示例直接拋出異常則完全沒有問題。如果真的遇到代碼出錯的意外情形,throw會關停代碼并提供一個漂亮的堆棧軌跡來解釋出錯原因。

這里真正的不妥之處在于,同樣的錯誤處理邏輯(即if(err) throw err)重復了多達3次!在4.2.2節,我們會看到Async.js如何幫助減少這種重復。

Async.js的函數式寫法
我們想把同步迭代器所使用的filter和forEach方法替換成相應的異步方法。Async.js給了我們兩個選擇。

async.filter和async.forEach,它們會并行處理給定的數組。
async.filterSeries和async.forEachSeries,它們會順序處理給定的數組。
并行運行這些異步操作應該會更快,那為什么還要使用序列式方法呢?原因有兩個。

前面提到的工作流次序不可預知的問題。我們確實可以先把結果存儲成數組,然后再joining(聯接)數組來解決這個問題,但這畢竟多了一個步驟。
Node及其他任何應用進程能夠同時讀取的文件數量有一個上限。如果超過這個上限,操作系統就會報錯。如果能順序讀取文件,則無需擔心這一限制。
所以現在先搞明白async.forEachSeries再說。下面使用了Async.js的數據收集方法,直接改寫了同步版本的代碼實現。

Asyncjs/forEachSeries.js

復制代碼 代碼如下:

var async = require('async');
var fs = require('fs');
process.chdir('recipes'); // 改變工作目錄
var concatenation = '';

var dirContents = fs.readdirSync('.');

async.filter(dirContents, isFilename, function(filenames) {
  async.forEachSeries(filenames, readAndConcat, onComplete);
});

function isFilename(filename, callback) {
  fs.stat(filename, function(err, stats) {
    if (err) throw err;
    callback(stats.isFile());
  });
}

function readAndConcat(filename, callback) {
  fs.readFile(filename, 'utf8', function(err, fileContents) {
    if (err) return callback(err);
    concatenation += fileContents;
    callback();
  });
}

function onComplete(err) {
  if (err) throw err;
  console.log(concatenation);
}

現在我們的代碼漂亮地分成了兩個部分:任務概貌(表現形式為async.filter調用和async.forEachSeries調用)和實現細節(表現形式為兩個迭代器函數和一個完工回調onComplete)。

filter和forEach并不是僅有的與標準函數式迭代方法相對應的Async.js工具函數。Async.js還提供了以下方法:

reject/rejectSeries,與filter剛好相反;
map/mapSeries,1:1變換;
reduce/reduceRight,值的逐步變換;
detect/detectSeries,找到篩選器匹配的值;
sortBy,產生一個有序副本;
some,測試是否至少有一個值符合給定標準;
every,測試是否所有值均符合給定標準。
這些方法是Async.js的精髓,令你能夠以最低的代碼重復度來執行常見的迭代工作。在繼續探索更高級的方法之前,我們先來看看這些方法的錯誤處理技術。

Async.js的錯誤處理技術
要怪就怪Node的fs.exists首開這一先河吧!而這也意味著使用了Async.js數據收集方法(filter/filterSeries、reject/rejectSeries、detect/detectSeries、some、every等)的迭代器均無法報告錯誤。

對于非布爾型的所有Async.js迭代器,傳遞非null/undefined的值作為迭代器回調的首參數將會立即因該錯誤值而調用完工回調。這正是readAndConcat不用throw也能工作的原因。

Asyncjs/forEachSeries.js

復制代碼 代碼如下:

function readAndConcat(filename, callback) {
  fs.readFile(filename, 'utf8', function(err, fileContents) {
    if (err) return callback(err);
    concatenation += fileContents;
    callback();
  });
}

所以,如果callback(err)確實是在readAndConcat中被調用的,則這個err會傳遞給完工回調(即onComplete)。Async.js只負責保證onComplete只被調用一次,而不管是因首次出錯而調用,還是因成功完成所有操作而調用。

Asyncjs/forEachSeries.js

復制代碼 代碼如下:

function onComplete(err) {
  if (err) throw err;
  console.log(concatenation);
}

Node的錯誤處理約定對Async.js數據收集方法而言也許并不理想,但對于Async.js的所有其他方法而言,遵守這些約定可以讓錯誤干凈利落地從各個任務流向完工回調。下一節會看到更多這樣的例子。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产a级全部精品| 亚洲国产中文字幕久久网| 日韩美女视频在线观看| 98精品国产高清在线xxxx天堂| 日韩成人高清在线| 国产欧美日韩丝袜精品一区| 亚洲韩国青草视频| 草民午夜欧美限制a级福利片| 亚洲精品国产拍免费91在线| 国产综合在线观看视频| 国产精品v片在线观看不卡| 亚洲国产女人aaa毛片在线| 国产精品狠色婷| 日韩欧美亚洲成人| 日韩电视剧免费观看网站| 亚洲影视九九影院在线观看| 国产精品一区二区三区免费视频| 欧美激情中文字幕乱码免费| 亚洲一区久久久| 亚洲国产精彩中文乱码av| 国产91精品在线播放| 欧美在线视频免费播放| 精品亚洲一区二区三区在线观看| 亚洲人成电影网站色www| 日韩av在线影院| 欧美裸体xxxx极品少妇软件| 91精品在线看| 久久免费视频这里只有精品| 国产精品精品久久久久久| 久久久久在线观看| 91精品国产成人www| 国产精品视频成人| 国产精品91久久久| 欧美做受高潮1| 欧美大荫蒂xxx| 亚洲无av在线中文字幕| 亚洲人成网站色ww在线| 美女扒开尿口让男人操亚洲视频网站| 日韩免费视频在线观看| 2019中文字幕全在线观看| 国产一区视频在线播放| 亚洲欧美国产一区二区三区| 欧美在线性视频| 久久中国妇女中文字幕| 国产亚洲激情视频在线| 国产自产女人91一区在线观看| 国产玖玖精品视频| 国产精品一区二区在线| 欧美性xxxxxx| 日韩成人激情在线| 欧美日韩成人在线观看| 色偷偷av一区二区三区| 亚洲3p在线观看| 国产精品久久久久久久av大片| 欧美电影《睫毛膏》| 亚洲精品女av网站| www.亚洲天堂| 国产做受高潮69| 国产精品一区二区三区毛片淫片| 成人黄色免费在线观看| 91社区国产高清| 亚洲在线视频观看| 亚洲精品国产拍免费91在线| 国产美女被下药99| 91夜夜揉人人捏人人添红杏| 久久91亚洲精品中文字幕奶水| 美女国内精品自产拍在线播放| 欧美中文在线字幕| 亚洲欧洲日产国码av系列天堂| 久久久久亚洲精品国产| 久久亚洲精品国产亚洲老地址| 国产噜噜噜噜噜久久久久久久久| 欧美大片欧美激情性色a∨久久| 亚洲高清色综合| 中文精品99久久国产香蕉| 欧美中文在线视频| 在线a欧美视频| 日韩精品在线免费| 欧美影院久久久| 日韩电影免费观看在线| 国产精品视频久久久| 日韩av电影免费观看高清| 中文字幕少妇一区二区三区| 欧美极品少妇xxxxⅹ喷水| 久久男人av资源网站| 海角国产乱辈乱精品视频| 日韩欧美在线国产| 久久久之久亚州精品露出| 亚洲精品自在久久| 国产亚洲精品一区二区| 亚洲精品色婷婷福利天堂| 久久精品国产一区二区电影| 国产在线视频欧美| 亚洲福利在线看| 亚洲一二在线观看| 日韩a**站在线观看| 成人免费xxxxx在线观看| 国内精品久久久久久| 久久久久北条麻妃免费看| 亚洲成avwww人| 亚洲精品欧美日韩专区| 日本精品在线视频| 97热在线精品视频在线观看| 亚洲一区第一页| 91久热免费在线视频| 国产精品永久免费在线| 九九热r在线视频精品| 一本色道久久综合狠狠躁篇怎么玩| 国产精品高潮呻吟久久av无限| 裸体女人亚洲精品一区| 日韩av成人在线| 日韩视频一区在线| 亚洲欧美中文日韩v在线观看| 亚洲福利在线播放| 欧美俄罗斯乱妇| 日韩视频免费在线| 国产91成人video| 日韩视频在线观看免费| 久久精品一偷一偷国产| 久久精品国产欧美亚洲人人爽| 97成人超碰免| 尤物九九久久国产精品的分类| 日韩精品中文字幕久久臀| 亚洲人午夜精品| 91精品啪aⅴ在线观看国产| 69国产精品成人在线播放| 国产欧美日韩丝袜精品一区| 国产成人a亚洲精品| 亚洲丝袜av一区| 日韩美女免费观看| 成人www视频在线观看| 国产成人精品一区二区| 久久人人爽人人爽人人片av高请| 日韩中文字幕在线| 91久久久久久| 久久精品成人动漫| 欧美激情综合色| 国产精品高潮呻吟视频| 亚洲片av在线| 啪一啪鲁一鲁2019在线视频| 中文字幕一区二区三区电影| 久久久久一本一区二区青青蜜月| 亚洲黄色www| 亚洲欧美日韩国产中文| 成人午夜一级二级三级| 国产精品电影一区| 欧美在线视频免费观看| 国产午夜精品全部视频在线播放| 日韩精品视频免费在线观看| 欧美日韩免费观看中文| 超碰97人人做人人爱少妇| 久久久人成影片一区二区三区| 中国人与牲禽动交精品| 91亚洲精品一区| 91中文在线视频| 国产热re99久久6国产精品| 日韩av在线一区| 欧美另类在线播放| 国产精品视频26uuu| 成人a在线视频| 高清日韩电视剧大全免费播放在线观看| 在线观看日韩av| 亚洲精品动漫100p| 国产精品直播网红|