iT邦幫忙

5

javascript的範例學習:以jQuery為例(七),callback 之一

timloo 2012-08-05 14:29:2111191 瀏覽
  • 分享至 

  • xImage
  •  

在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不起來,真是高深的語法。沒法測試另一種語法的效果。


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
ted99tw
iT邦高手 1 級 ‧ 2012-08-05 16:02:11


以匿名身份按推....

0
timloo
iT邦研究生 2 級 ‧ 2012-08-06 17:36:50

function裏,可以call function,這是普通的call。

function裏又call自己,這叫遞迴。

function的參數也是一個function,這叫callback。

如果把這三者結合起來,除了增加程式的複雜度,還真沒其他特別的意思。

我要留言

立即登入留言