麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 語言 > 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教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 视频一区二区国产 | 亚洲电影在线观看高清免费 | 92看片淫黄大片欧美看国产片 | 黄色网址电影 | 日韩毛片毛片久久精品 | 久久免费综合视频 | 91久久另类重口变态 | 欧美国产精品一区二区 | 国产剧情在线观看一区二区 | 全网免费毛片 | 久草在线视频首页 | 澳门一级淫片免费视频 | 99精品视频在线观看免费播放 | 亚洲乱码精品久久久久 | 亚州精品在线视频 | av电影在线观看网址 | 成人在线视频精品 | 久久久一区二区三区四区 | 亚洲一二三久久 | 色网在线视频 | 中午字幕无线码一区2020 | 九九热视频这里只有精品 | 欧美 日韩 国产 成人 | hd极品free性xxx一护士 | 欧美一级做一级爱a做片性 91在线视频观看 | 国产成人精品免费视频大全办公室 | 污污的视频在线观看 | 成人免费毛片片v | 香蕉视频99| 亚洲精品一区中文字幕 | 中文字幕一区在线观看视频 | 毛片福利| 久色乳综合思思在线视频 | 666sao| 国产福利视频 | 蜜桃久久一区二区三区 | 作爱在线观看 | 一区二区三区欧美精品 | 日本最新免费二区三区 | 成年性羞羞视频免费观看无限 | 好骚综合在线 |