在jQuery源碼裏,如果你用callback 去搜尋,可以得到不少的結果,
8378: show: function( speed, easing, callback ) {
8382: return this.animate( genFx("show", 3), speed, easing, callback );
8425: hide: function( speed, easing, callback ) {
8427: return this.animate( genFx("hide", 3), speed, easing, callback);
8460: toggle: function( fn, fn2, callback ) {
8473: this.animate(genFx("toggle", 3), fn, fn2, callback);
8479: fadeTo: function( speed, to, easing, callback ) {
8481: .animate({opacity: to}, speed, easing, callback);
8484: animate: function( prop, speed, easing, callback ) {
8485: var optall = jQuery.speed( speed, easing, callback );
8681: // timers currently will call their complete callbacks, which will dequeue
8721: jQuery.fn[ name ] = function( speed, easing, callback ) {
8722: return this.animate( props, speed, easing, callback );
還有
8191: var callback;
8243: callback = function( _, isAbort ) {
8257: if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
8260: callback = undefined;
8330: // we need to manually fire the callback
8332: callback();
在這段引用裏,可知本來描述一種程式呼叫機制的callback在jQuery裏是指一個具體function變數,當參數傳來傳去。
wiki裏,http://en.wikipedia.org/wiki/Callback_(computer_programming),也有回調函數的解釋,在形式上就是把一個函數當成參數來傳給另一個函數。。
這個圖可以說明這件事。
本篇以練習這個型式為主。筆者日常工作中較少這種寫法的經驗。
LAB1:
改自http://blog.joomla.org.tw/javascript/54-general/81-javascript-functon-basic.html
function addOne(a) {
return a + 1;
}
function minusOne(b) {
return b - 1;
}
function multiplyByTwo(a, b, c, callback) {
var i, ar = [];
for(i = 0; i < 3; i++) {
document.write("arguments="+arguments[i]+"<br>");
ar[i] = callback(arguments[i] * 2);
document.write(i+"<br>");
document.write(ar[i]+"<br>");
}
return ar;
}
//直接將函數名稱傳入
//myarr = multiplyByTwo(1, 2, 3, addOne);
//document.write(myarr+"<br>");
//直接用匿名函數當作參數
//myarr = multiplyByTwo(1, 2, 3, function(a){return a + 1});
//document.write(myarr+"<br>");
myarr = multiplyByTwo(1, 2, 3, minusOne);
document.write(myarr+"<br>");
myarr = multiplyByTwo(1, 2, 3, function(b){return b - 1});
document.write(myarr+"<br>");
myarr = multiplyByTwo(0, 1, 2, function(b){return b - 1});
document.write(myarr+"<br>");
順便了解arguments[i]的用法,及document.write把過程中的值印出,
可以用匿名函數來代替具名函數
LAB2:
改自http://xiayuanfeng.iteye.com/blog/301453
function invoke_and_add(a,b){
return a+b;
}
function one(){
return 1;
}
function two(){
return 2;
}
function three(){
return 3;
}
function four(){
return 4;
}
document.write( invoke_and_add(one(), two())+"<br>"); //"兩函數相加:"
document.write( three()- four() +"<br>");
可以看出,一般的直接呼叫,和透過一個函數,經由觸動參數去呼叫,效果差不多,
原POST文,invoke_and_add(one ,two); ,不work, 改成
invoke_and_add(one(), two())就WORK了!!
LAB3:
改自http://recurial.com/programming/understanding-callback-functions-in-javascript/
var func_multiply = new Function("arg1", "arg2", "return arg1 * arg2;");
//var func_multiply = new Function(arg1, arg2, return arg1 * arg2);
//var func_multiply = new Function(arg1, arg2, "return arg1 * arg2;");
document.write(func_multiply(5,10)+"<br>"); // => 50
具名函數的另一種寫法,註解掉的兩個寫法,都不work.
小結:在中文WIKI裏沒有翻的一段,
英文WIKI裏寫著,
There are two types of callbacks: blocking callbacks (also known as synchronous callbacks or just callbacks) and deferred callbacks (also known as asynchronous callbacks).
兩種回呼設計,一種是即時同步的,一種是延後的非同步的。這裏的asynchronous就是AJAX的A。
These two design choices differ in how they control data flow at runtime.
這種設計不同於執行時期對資料流的控制。
While blocking callbacks are invoked before a function returns (in the example above: main), deferred callbacks may be invoked after a function returns.
blocking回呼在主函數返回之前被觸發,延後的回呼在主函數返回之後觸發。
以下就不翻譯了。
The above is an example of a blocking callback. Deferred callbacks are often used in the context of I/O operations or event handling. While deferred callbacks imply the existence of multiple threads, blocking callbacks are often (but not always) relying on a single thread. Therefore blocking callbacks are no common cause for synchronization.
在dreamerslab裏有一個例子:
http://dreamerslab.com/blog/tw/javascript-callbacks/
兩個函數,do_a,do_b, 如果do_a執行時間長於do_b,如果 do_a;do_b;這樣的順序執行,
顯然do_b會先完成,那改成
do_a( function(){
do_b();
});
這樣的話,do_a執行完後,才會執行do_b。
不過就型的角度來看,這裏面還是有一點玄機,
並不是
do_a(
do_b();
);
這樣的型式。
但是它要達成的效果有延後(DEFERRED)的效果,dreamerslab的code,改了一會兒,還是RUN不起來,真是高深的語法。沒法測試另一種語法的效果。
function裏,可以call function,這是普通的call。
function裏又call自己,這叫遞迴。
function的參數也是一個function,這叫callback。
如果把這三者結合起來,除了增加程式的複雜度,還真沒其他特別的意思。