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

首頁 > 語言 > JavaScript > 正文

深入淺析NodeJs并發異步的回調處理

2024-05-06 16:26:39
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了NodeJs并發異步的回調處理的相關資料,需要的朋友可以參考下
 

這里說并發異步,并不準確,應該說連續異步。NodeJs單線程異步的特性,直接導致多個異步同時進行時,無法確定最后的執行結果來回調。舉個簡單的例子:

for(var i = 0; i < 5; i++) {  fs.readFile('file', 'utf-8', function(error, data){});} 

連續發起了5次讀文件的異步操作,很簡單,那么問題來了,我怎么確定所有異步都執行完了呢?因為要在它們都執行完后,才能進行之后的操作。相信有點經驗的同學都會想到使用記數的方式來進行,但如何保證記數正確又是一個問題。仔細想想:

回調是一個函數,每個異步操作時將計數器+1,當每個異步結束時將計數器-1,通過判斷計數器是否為0來確定是否執行回調。這個邏輯很簡單,需要一個相對于執行時和回調時的全局變量作為計數器,而且要在傳給異步方法是執行+1的操作,而且之后將返回一個用來回調的函數,有點繞,不過看看Js函數的高級用法:

var pending = (function() {  var count = 0;  return function() {    count++;    return function() {      count--;      if (count === 0) {        // 全部執行完畢      }    }  }}); 

當pending調用時,即pending(),比如:

var done = pending(); 

這時計數變量count即被初始化為0,返回的函數附給了done,這時如果執行done(),會是什么?是不是直接執行pending返回的第一個函數,即:pending()(),這個執行又是什么,首先將計數變量count+1,又返回了一個函數,這個函數直接當做callback傳給異步的方法,當執行這個callback的時候,首先是將計數變量count-1,再判斷count是否為0,如果為0即表示所有的異步執行完成了,從而達到連續的異步,同一回調的操作。

關鍵就在兩個return上,簡單的說:

第一個return的函數是將count+1,接著返回需要回調的函數

第二個return的函數就是需要回調的函數,如果它執行,就是將count-1,然后判斷異步是否全部執行完成,完成了,就回調

看個實際點的例子,讀取多個文件的異步回調:

var fileName = ['1.html', '2.html', '3.html'];var done = pending(function(fileData) {  console.log('done');  console.log(fielData);});for(var i = 0; i < fileName.lenght; i++) {  fs.readFile(fileName[i], 'utf-8', done(fileName[i]));}

其中的done,即用pending方法包起了我們想回調執行的方法,當計數器為0時,就會執行它,那我們得改進一下pending方法:

var pending = (function(callback) {  var count = 0;  var returns = {};  console.log(count);  return function(key) {    count++;    console.log(count);    return function(error, data) {      count--;      console.log(count);      returns[key] = data;      if (count === 0) {        callback(returns);      }    }  }}); 

callback即為我們的回調函數,當var done = pending(callback)時,done其實已為第一個return的函數,它有一個參數,可以當做返回的值的下標,所以在循環體中done(fileName[i]),把文件名傳了進去。這個done()是直接執行的,它將count+1后,返回了要傳給異步方法的回調函數,如前面所說,這個回調函數里會根據計數變量來判斷是否執行我們希望執行的回調函數,而且把文件的內容傳給了它,即returns。好了,運行一下,相信能夠準確的看到運行結果。

0
1
2
3
2
1
0
done
{"1.html": "xxx", "2.html": "xxx", "3.html": "xxx"}

從計數上明顯能看出,從0-3再到0,之后就是我們的回調函數輸出了done和文件的內容。

這個問題解決了,我們要思考一下,如何讓這樣的方法封裝重用,不然,每次都寫pending不是很不科學嗎?

下面看看UnJs(我的一個基于NodeJs的Web開發框架)的處理方式,應用于模板解析中的子模板操作:

unjs.asyncSeries = function(task, func, callback) {  var taskLen = task.length;  if (taskLen <= 0) {    return;  }  var done = unjs.pending(callback);  for(var i = 0; i < taskLen; i++) {    func(task[i], done);  }} 

asyncSeries有三個參數,意思是:

task: 需要處理的對象,比如需要讀取的文件,它是一個列表,如果不是列表,或列表長度為0,它將不會執行

func: 異步方法,比如fs.readFile,就是通過它傳進去的

callback: 我們希望回調的方法

done和前面同理,它傳給了func,但并沒有執行,因為希望應用端能可控制參數,所以讓應用端去執行。

再看看處理子模板時的操作:

var subTemplate = [];var patt = //{/% include /'(.+)/' /%/}/ig;while(sub = patt.exec(data)) {  var subs = sub;  subTemplate.push([subs[0], subs[1]]);}unjs.asyncSeries(subTemplate, function(item, callback) {  fs.readFile('./template/' + item[1], 'utf-8', callback(item[0]));}, function(data) {  for(var key in data) {    html = html.replace(key, data[key]);  }}); 

subTemplate這個列表,是根據對子模板的解析生成的數據,它是一個二維的數組,每個子項的第一個值為子模板的調用文本,即:{% include 'header.html' %}這樣的字符串,第二個參數為子模板文件名,即:header.html

asyncSeries的第二個參數是的callback,實際上是第三個參數,也就是我們希望執行的回調函數經過pending處理的回調方法,如前面所說,在asyncSeries內部,它并沒有運行,而是到這里運行的,即:callback(item[0]),帶上了參數,因為后面還要根據這個參數將父模板中調用子模板的字符串替換為對應子模板的內容。

這樣子,只要需要連續異步時,就可以使用asyncSeries方法來處理了。因為異步的關系,程序的流程有點繞,可能開始不太好理解,即使熟悉了,也有可能突然想不明白,沒關系,比如,第二個參數中的callback實際是第三個參數生成的,開始可能你就會想,這個callback倒底是啥。還有就是pending的兩個return,也是不太好理解的,需要多想想。

好了,連續異步的回調使用Js函數的高級特性完成了。但NodeJs的異步性著實讓程序的控制很成問題,諸如還有連續異步,但要傳值的操作等,這些都是可以通過這樣的思路,變化一下即可實現的。

以上內容是小編給大家分享的NodeJs并發異步的回調處理的相關知識,希望大家喜歡。



注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久999精品免费| 精品久久香蕉国产线看观看亚洲| 欧美成人第一页| 亚洲第一精品夜夜躁人人躁| 欧美一级bbbbb性bbbb喷潮片| 日韩美女在线观看一区| 亚洲图中文字幕| 亚洲福利在线看| 日韩精品中文在线观看| 国产日韩在线观看av| 欧美精品在线观看91| 国产精品极品美女粉嫩高清在线| 91影院在线免费观看视频| 揄拍成人国产精品视频| 精品久久久久久久大神国产| 亚洲久久久久久久久久久| 欧美日韩福利视频| 国产精品美乳一区二区免费| 国产精品一区二区久久国产| 久久精品中文字幕一区| 欧美视频在线免费| 欧美日韩在线视频观看| 国产精品国模在线| 尤物九九久久国产精品的分类| 亚洲精品国产精品国自产在线| 亚洲xxx大片| 日韩大片在线观看视频| 日韩在线视频观看正片免费网站| 美日韩精品免费视频| 欧美成人精品xxx| 日本最新高清不卡中文字幕| 国产精品福利在线| 岛国av一区二区| 亚洲欧美视频在线| 超碰精品一区二区三区乱码| 欧美日韩亚洲激情| 97在线视频免费观看| 91精品国产综合久久香蕉922| 日本乱人伦a精品| 欧美在线视频观看免费网站| 欧美xxxx18性欧美| 精品国产一区久久久| 精品国产成人在线| 红桃视频成人在线观看| 精品久久久久久久久久久久久久| 亚洲qvod图片区电影| www.日本久久久久com.| 国产精品久久久久久久久久久久| 亚洲天堂色网站| 久久久久久久电影一区| 一本一本久久a久久精品综合小说| 欧美精品日韩三级| 国产免费观看久久黄| 成人黄色av免费在线观看| 另类少妇人与禽zozz0性伦| 日韩在线视频免费观看| 欧美精品久久久久久久久久| 亚洲成人a**站| 国产精品美女免费| 欧美一区第一页| 精品无人区乱码1区2区3区在线| 国产主播精品在线| 国产美女精彩久久| 日韩中文字幕国产| 欧美精品国产精品日韩精品| 91精品国产自产在线老师啪| 国产精品av免费在线观看| 97香蕉久久夜色精品国产| 欧美另类老肥妇| 亚洲第一区在线观看| 91精品国产乱码久久久久久蜜臀| 51午夜精品视频| 国产欧美日韩最新| 狠狠久久亚洲欧美专区| 成人黄色av网| 久久中文字幕在线视频| 亚洲国产精品va在线| 国产午夜精品美女视频明星a级| 伊人伊成久久人综合网站| 亚洲偷熟乱区亚洲香蕉av| 久久久久久久久综合| 国产精品第8页| 亚洲第一区在线观看| 久久久亚洲福利精品午夜| 久久人91精品久久久久久不卡| 78色国产精品| 黑人巨大精品欧美一区二区三区| 亚洲欧美制服中文字幕| www.日韩.com| 青青青国产精品一区二区| 国产成人拍精品视频午夜网站| 成人a级免费视频| 欧美激情视频在线| 美女福利视频一区| 欧美午夜片欧美片在线观看| 国产不卡av在线| 欧美日韩福利在线观看| 欧美视频在线观看免费| 午夜精品久久久久久久男人的天堂| 国产精品黄色影片导航在线观看| 日韩一区二区三区在线播放| 欧美在线欧美在线| 亚洲成人免费在线视频| 日韩在线视频免费观看| 日韩中文字幕免费| 亚洲人成五月天| 国产精品视频一区二区高潮| 97视频在线观看网址| 久久97久久97精品免视看| 91系列在线播放| 人人澡人人澡人人看欧美| 欧美精品18videos性欧美| 久久精品美女视频网站| 日韩av一区二区在线观看| 久久伊人91精品综合网站| 欧美特黄级在线| 亚洲天堂视频在线观看| 亚洲福利影片在线| 亚洲成人久久网| 色婷婷综合成人| 亚洲精品美女网站| 欧美性xxxxxx| 日韩人在线观看| 国产日韩欧美中文在线播放| 国产精品wwwwww| 久热爱精品视频线路一| 久久久999成人| 欧美成人中文字幕在线| 日日狠狠久久偷偷四色综合免费| 日韩一区二区三区在线播放| 亚洲最大激情中文字幕| 91沈先生在线观看| 亚洲人在线观看| 久久人人爽人人爽人人片亚洲| 91欧美日韩一区| 色综合久综合久久综合久鬼88| 8x拔播拔播x8国产精品| 国产精品三级美女白浆呻吟| 亚洲欧美自拍一区| 亚洲娇小xxxx欧美娇小| 午夜精品蜜臀一区二区三区免费| 欧美怡红院视频一区二区三区| 国产精品户外野外| 欧美日韩中文在线观看| 欧美在线亚洲一区| 91精品国产777在线观看| 欧美国产一区二区三区| 久久久久久久激情视频| 日韩精品电影网| 国产精品三级美女白浆呻吟| 欧美专区在线视频| 日韩有码在线视频| 91在线高清视频| 这里只有精品在线播放| 日韩美女主播视频| 国产一区二区在线免费视频| 成人国内精品久久久久一区| 欧美尤物巨大精品爽| 亚洲色图综合久久| 欧美极品欧美精品欧美视频| 亚洲天堂色网站| 国产一区二区美女视频| 欧美高清一级大片| 精品亚洲男同gayvideo网站|