關於
《Nodejs開發加密貨幣》,是一個加密貨幣產品的詳細開發文檔,涉及到使用Nodejs開發產品的方方面面,從前端到後臺、從服務器到客戶端、從PC到移動、加密解密等各個環節。代碼完全開源、文章免費分享。 相關資源見 http://ebookchain.org
前言
前面說過,在Nodejs的世界裏“事事皆回調”,學習使用Nodejs,最不可能迴避的就是“回調”(用“調回”更直觀些)。無法迴避,自然要積極面對,因此開源社區出現了很多代碼流程控制的解決方案。比如:bluebird,q,以及這裏要圖解的async。
這種基礎性的技術,社區的文檔極其豐富,顯然我們沒必要重複前人,所以這裏採取圖解和歸類的形式,從操作方面入手。另外,細心的朋友也會從前面的源碼分析中發現,億書大量使用了aysnc,全面掌握它,對於理解和編碼,事倍功半。
這是async在https://npmjs.org
上的排名,除了lodash,就是它了。而且,bluebird和q也都在前10,也基本說明,使用流程控制組件是Nodejs處理回調的標配。
概念定義
官方介紹:
Async is a utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript.
簡單翻譯:Async是一個爲處理異步Js提供簡單、直接、強大功能的實用模塊。
流程類別
僅僅爲了好區分、好記憶,簡單彙總一下,全部流程應該是下面三種情況(並非官方描述):
1.基本流程
從程序(多個函數)執行順序的角度考量,包括順序執行、並行執行、混合執行等基本流程。如果把函數間是否有依賴、是否限制函數執行的數量等,又可繼續演化出很多種。
2.循環流程
基於某個條件的循環操作,根據條件使用方式,提供了諸多函數。
3.集合流程
上面都是針對一個或一組數據的處理。現實中,通常要對大批相同或相似的數據,比如:大批文件、地址,進行集中處理。顯然,我們第一反應是循環調用上述流程即可,不過Async提供了對集合進行異步操作的工具方法(util),如forEach等,就叫它“集合流程”吧。
使用流程的概念可以明確告訴我們,當使用async.forEach()
的時候,是在異步操作,與單純的forEach
方法調用是有區別的。
用法分類
async提供了70多個實用的函數,所有這些函數都遵守一個約定:你定義的異步函數(當作一個任務),最後一個參數必須是callback函數;該callback函數的第一個參數必須是Error,且callback函數調用一次。
這些函數大致分爲3類,分別對應上面的3個類別:
1.基本型(一次多任務)
這對應基本流程和演化流程部分,對一項事務,多個任務的操作,調用形式爲
async.funName(tasks, callback(error, results))
這裏的funName,包括:series, parallel(parallelLimit), waterfall, auto(autoInject)等。這裏的tasks可以是Array形式,也可以是Json形式,或者僅支持其中一種。
如果全部函數執行成功,callback裏的results也會對應tasks的形式,將已經執行函數的結果轉化爲Array或Json形式;如果tasks中有一個函數出錯,就會終止後續執行,調用callback,error就是該函數的錯誤信息,results或僅包含已經執行的結果、或同時包含未執行函數的結果佔位符,或什麼都不包含直接忽略。至於results具體是什麼,一個log
語句,自然就能知曉,不必去查文檔。
2.循環型(多次單任務)
根據條件不同,可以使用下面的形式調用
async.funName(test, fn, callback)
或
async.doFunName(fn, test, callback)
這裏的funName,包括:whilst(doWhilst),until(doUntil), during(doDuring), retry(retryable),times(timesSeries, timesLimit)、forever(該函數的條件test就不用了,已經暗含條件)。
這裏的條件值可以是表達式函數,或具體的次數。區分fn與test的順序,很簡單,只要用英文的意思去理解就可以,比如:async.doWhilst(),必然是先do,後whilst,因此參數自然是async.doWhilst(fn, test, callback)
3.集合型(多次單任務)
這個官方沒有當作流程表述,當作集合操作方法提供的,是我個人的理解和杜撰。我覺得把它歸爲流程控制更好接受和理解。因此,仿造上面的循環型調用方法,只要將條件test改爲一個集合就好,集合全部使用數組array形式。
async.funName(arr, iteratee, [callback])
這裏的funName,包括:
each, eachSeries, eachLimit
forEachOf, forEachOfSeries, forEachOfLimit
map, mapSeries, mapLimit
filter, filterSeries, filterLimit
reject, rejectSeries, rejectLimit
reduce, reduceRight
detect, detectSeries, detectLimit
sortBy
some, someLimit, someSeries
every, everyLimit, everySeries
concat, concatSeries
當然,async還明確提供了其他幾個流程控制,比如:compose,seq,applyEach(applyEachSeries),queue(priorityQueue),cargo,iterator,race等。
另外,還有幾個Util(工具)函數,如:apply,nextTick,memoize,unmemoize,ensureAsync,constant,asyncify,wrapSync,log,dir,noConflict,timeout等,這些都能極大的方便代碼撰寫,改善代碼性能。
腦圖
上述解釋和方法,我們全部放在一張腦圖裏,結合場景,按圖索驥,能夠很快找到正確的處理方法。
源碼解讀
看看Ebookcoin
裏面,async的使用吧。因爲在《入口程序app.js解讀》裏,已經提及,這裏就不說了,以後遇到再解釋。
趣味實踐
Async官方文檔提供了很多實例, 簡單直觀。這裏,我們不再舉例,而是提出一個趣味問題,供思考:
問題:Aysnc能否用於遞歸調用,比如:某個爬蟲程序,遍歷某文件夾下全部文件信息的函數等?爲什麼?
總結
這又是一篇老生常談的技術分享,但寫完之後,對異步操作的流程管理,更加清晰了。Aysnc很好,但也不是萬能的,它對於那些反覆自調用的代碼就無能爲力,因爲限制任務的回調就是一次。後續,有機會還會繼續深入學習研究它。
鏈接
本系列文章即時更新,若要掌握最新內容,請關注下面的鏈接
本源文地址: https://github.com/imfly/bitcoin-on-nodejs
電子書閱讀: http://bitcoin-on-nodejs.ebookchain.org