1. 同步和非同步執行順序抽像想像
所以 sync 部份跑完才會開始跑 async 或是在 even driven 才跑 async 有點像下圖
async 部份是看誰先排進 async query 內誰先優先執行
所以像
var async_function = function(val, callback){
process.nextTick(function(){
callback(val);
});
};
async_function(1, function(val) {
console.log(val);
async_function(2, function(val) {
console.log(val);
async_function(3, function(val) {
console.log(val);
});
});
});
console.log(100);
會列出
100
1
2
3
所以在同一個 async scope 會保證其順序性 1 > 2 > 3
再看一個範例,在 sync 等地方再加一個不同的 async scope
var async_function = function(val, callback){
process.nextTick(function(){
callback(val);
});
};
async_function(1, function(val) {
console.log(val);
async_function(2, function(val) {
console.log(val);
async_function(3, function(val) {
console.log(val);
});
});
});
console.log(100);
async_function(4, function(val) {
console.log(val);
async_function(5, function(val) {
console.log(val);
async_function(6, function(val) {
console.log(val);
});
});
});
會列出
100 1 4 2 5 3 6
1 > 2 > 3
4 > 5 > 6
但不同 scope 會形成交叉,因為在 sync 的 scope 時 1>4 是這順序排進 queue
而印 1 後,2 被排進 queue 內,4 被執行
4印出後,5排進 queue 內,2被執行,以此類堆
推薦可以看下面這篇,會更清楚為什麼會這樣,雖然主要在講為什麼 async 會比較快,但圖片說明很棒,淺顯易懂
http://blogger.gtwang.org/2014/02/node-js-is-faster-than-java-for-concurrent-data-processing-operations.html
另外這篇在講 node.js 的 process queue
http://fred-zone.blogspot.tw/2012/03/nodejs.html
2. 區分是 sync 的 function 還是 async 的 function
這點 JSDC 2015 Jonathan 也有提到
http://www.jongleberry.com/async-control-flow/assets/player/KeynoteDHTMLPlayer.html#8
大部份只要有 callback 幾乎都是 async 的 function
除了 array iteration methods 操作,像 forEach、map...等
(Ref:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype#Iteration_methods)
另外很多 function 如果結尾有 sync 就是同步版的 function
像 fs 內就有,例如 fs.open 是 async 的版本 fs.openSync 就是 sync 的版本
3. Control Flow (俗稱 callback hell)
因為 callback 的方式導致閱讀程式變成很難
而且很多整理程式的方法,都不太適用,例如 design pattern
目前常聽到的解決是使用這三個方法來解:aync、promise、async/await
aync:
https://github.com/caolan/async
我個人目前都是用這個
比較常用的像有 waterfall
promise:
這裡指的是 ES6 的 promise
不過我也還沒研究:D
npm 有一些類似的 modules
async/await:
這裡指的是 ES7 的
npm 也有幾個,但都會降低效能
https://github.com/yortus/asyncawait#5-performance
像這個會降 20%左右
不過另一個經驗在大部份的 refactory 書(像易讀程式之美學)都有提到。
儘量把程式 function 化,讓 function 和 method 只做一件事,即使在 callback hell 中,也能讓程式變的比較好讀。
題外話
http://www.jongleberry.com/async-control-flow/assets/player/KeynoteDHTMLPlayer.html#12
有提到儘量使用 thrown new Error("boom") 取代 thrown "boom"
這樣才有 stack trace 能看
Reference:
http://blogger.gtwang.org/2014/02/node-js-is-faster-than-java-for-concurrent-data-processing-operations.html
http://fred-zone.blogspot.tw/2012/03/nodejs.html
http://www.jongleberry.com/async-control-flow/assets/player/KeynoteDHTMLPlayer.html#8
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype#Iteration_methods
https://github.com/caolan/async
https://github.com/yortus/asyncawait#5-performance
沒有留言:
張貼留言