[API-d15] - [Javascript 番外篇] Javascript callback, event
這幾天會探討 javascript 的特性,由於比較少在寫 js ,因此有錯請指正
javascript 有個特性:event
意思就是說,javascript 中,所有的事情都是由事件驅動的
如果說有寫過 web 前端的話,
其實呼叫 button.click function 時
並不會馬上執行 click 裡面的動作
而是加了一個 click 的 listener
等到 button 被 click 後,才會執行 click 裡面的程式碼
所以寫習慣一般 procedure 的程式會有點不太習慣
舉個 procedure 的例子,下面有五件事想要做:
煮飯(); // 10 分鐘
接電話(); // 1 分鐘
吃麵(); // 5 分鐘
丟垃圾(); // 7 分鐘
一般的程式會是照順序執行
也就是 煮飯完 -> 接電話 -> 吃麵 -> 丟垃圾
總執行時間 = 23 分鐘
但是如果把這段 code 丟給 javascript 執行的話
煮飯(); // 10 分鐘
接電話(); // 1 分鐘
吃麵(); // 5 分鐘
丟垃圾(); // 7 分鐘
就變成同時做煮飯,接電話,吃麵,丟垃圾了!
為了要預防這件事,有些事情還是有順序性的,
因此就要使用到 javascript callback 的特性
煮飯(function() {
吃飯(function() {
接電話(function() {
丟垃圾();
});
});
});
意思就是煮飯完吃飯,吃完飯接電話,接完電話丟垃圾
以下有一個範例:
function wash() {
setTimeout(function() {
console.log("wash");
}, 1000);
}
function eat() {
setTimeout(function() {
console.log("eat");
}, 5000);
}
function running() {
setTimeout(function() {
console.log("running");
}, 3000);
}
function doHouseWork() {
wash();
eat();
running();
}
doHouseWork();
做家事執行了三件事,wash, eat, 和 running
其中每件事都設定不同的完成時間
以 procedure 的程式執行方式來看,在這邊用 ruby 舉例:
def wash
sleep 1
puts "wash"
end
def eat
sleep 5
puts "eat"
end
def running
sleep 3
puts "running"
end
def doHouseWork
wash
eat
running
end
doHouseWork
是會 wash 1 秒後,接著 eat 5 秒,再 running 3 秒
所以總共是 9 秒
output 的順序會是:
wash // 1 秒
eat // 5 秒
running // 3 秒
但是在 javascript 中,output 的順序卻是:
wash // 1 秒
running // 3 秒
eat // 5 秒
所以總長度是 5 秒
那今天假設想要讓 javascript 有順序性時該怎麼辦?
拿上面的例子作修改的話:
function wash(callback) {
setTimeout(function() {
console.log("wash");
callback.call();
}, 1000);
}
function eat(callback) {
setTimeout(function() {
console.log("eat");
callback.call();
}, 5000);
}
function running() {
setTimeout(function() {
console.log("running");
}, 3000);
}
function doHouseWork(callback) {
console.log("doing house work");
callback.call();
}
doHouseWork(function(){
wash(function() {
eat(function() {
running();
});
});
});
很不錯的特性,但是也要特別對於這種特性作處理
有個 lib 很好用,async.js
來源
下回待續!