中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

用NODE.JS中的流編寫工具是要注意的事項
來源:易賢網 閱讀:1600 次 日期:2016-08-04 15:22:26
溫馨提示:易賢網小編為您整理了“用NODE.JS中的流編寫工具是要注意的事項”,方便廣大網友查閱!

Node.js中的流十分強大,它對處理潛在的大文件提供了支持,也抽象了一些場景下的數據處理和傳遞。正因為它如此好用,所以在實戰中我們常常基于它來編寫一些工具 函數/庫 ,但往往又由于自己對流的某些特性的疏忽,導致寫出的 函數/庫 在一些情況會達不到想要的效果,或者埋下一些隱藏的地雷。本文將會提供兩個在編寫基于流的工具時,私以為有些用的兩個tips。

一,警惕EVENTEMITTER內存泄露

在一個可能被多次調用的函數中,如果需要給流添加事件監聽器來執行某些操作。那么則需要警惕添加監聽器而導致的內存泄露:

'use strict';

const fs = require('fs');

const co = require('co');

function getSomeDataFromStream (stream) {

 let data = stream.read();

 if (data) return Promise.resolve(data);

 if (!stream.readable) return Promise.resolve(null);

 return new Promise((resolve, reject) => {

  stream.once('readable', () => resolve(stream.read()));

  stream.on('error', reject);

  stream.on('end', resolve);

 })

}

let stream = fs.createReadStream('/Path/to/a/big/file');

co(function *() {

 let chunk;

 while ((chunk = yield getSomeDataFromStream(stream)) !== null) {

  console.log(chunk);

 }

}).catch(console.error);

在上述代碼中,getSomeDataFromStream函數會在通過監聽error事件和end事件,來在流報錯或沒有數據時,完成這個Promise。然而在執行代碼時,我們很快就會在控制臺中看到報警信息:(node) warning: possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit.,因為我們在每次調用該函數時,都為傳入的流添加了一個額外的error事件監聽器和end事件監聽器。為了避免這種潛在的內存泄露,我們要確保每次函數執行完畢后,清除所有此次調用添加的額外監聽器,保持函數無污染:

function getSomeDataFromStream (stream) {

 let data = stream.read();

 if (data) return Promise.resolve(data);

 if (!stream.readable) return Promise.resolve(null);

 return new Promise((resolve, reject) => {

  stream.once('readable', onData);

  stream.on('error', onError);

  stream.on('end', done);

  function onData () {

   done();

   resolve(stream.read());

  }

  function onError (err) {

   done();

   reject(err);

  }

  function done () {

   stream.removeListener('readable', onData);

   stream.removeListener('error', onError);

   stream.removeListener('end', done);

  }

 })

}

二,保證工具函數的回調在處理完畢數據后才被調用

工具函數往往會對外提供一個回調函數參數,待處理完流中的所有數據后,帶著指定值觸發,通常的做法是將回調函數的調用掛在流的end事件中,但如果處理函數是耗時的異步操作,回調函數則可能在所有數據處理完畢前被調用:

'use strict';

const fs = require('fs');

let stream = fs.createReadStream('/Path/to/a/big/file');

function processSomeData (stream, callback) {

 stream.on('data', (data) => {

  // 對數據進行一些異步耗時操作

  setTimeout(() => console.log(data), 2000);

 });

 stream.on('end', () => {

  // ...

  callback()

 })

}

processSomeData(stream, () => console.log('end'));

以上的代碼callback回調可能會在數據并未被全部處理時就被調用,因為流的end事件的觸發時機僅僅是在流中的數據被讀完時。所以我們需要額外地對數據是否已處理完進行檢查:

function processSomeData (stream, callback) {

 let count = 0;

 let finished = 0;

 let isEnd = false;

 stream.on('data', (data) => {

  count++;

  // 對數據進行一些異步耗時操作

  setTimeout(() => {

   console.log(data);

   finished++;

   check();

  }, 2000);

 });

 stream.on('end', () => {

  isEnd = true;

  // ...

  check();

 })

 function check () {

  if (count === finished && isEnd) callback()

 }

}

這樣一來,回調便會在所有數據都處理完畢后觸發了。

更多信息請查看網絡編程
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!

2026國考·省考課程試聽報名

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
云南網警備案專用圖標
聯系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網
云南網警報警專用圖標
主站蜘蛛池模板: 东辽县| 祁连县| 盐池县| 思茅市| 安国市| 平邑县| 察隅县| 滁州市| 彭水| 二连浩特市| 定西市| 宁安市| 雷山县| 乡宁县| 柳河县| 巫山县| 闽侯县| 团风县| 辽宁省| 洪雅县| 洞口县| 绵竹市| 裕民县| 长治县| 宁化县| 星子县| 泽州县| 玛多县| 寿光市| 兴宁市| 浑源县| 龙门县| 义乌市| 鸡泽县| 游戏| 株洲县| 安仁县| 兴和县| 怀宁县| 泸西县| 怀远县|