告訴你什么是JavaScript回調(diào)函數(shù)

沒啥事情隨便寫了一個js的回調(diào)函數(shù)希望能幫助想要學(xué)習(xí)的(我接觸js時間不長,對回調(diào)的理解還是比較膚淺,如有錯誤希望大家指出 謝謝。){下一篇寫java 接口回調(diào)}

這里先引入幾個概念(baidu來的希望對大家有所幫助)

*函數(shù)也是對象

想弄明白回調(diào)函數(shù)罐监,首先的清楚地明白函數(shù)的規(guī)則。在javascript中,函數(shù)是比較奇怪的,但它確確實實是對象晨炕。確切地說,函數(shù)是用Function()構(gòu)造函數(shù)創(chuàng)建的Function對象毫炉。function對象包含一個字符串瓮栗,字符串包含函數(shù)的javascript代碼。假如你是從C語言或者java語言轉(zhuǎn)過來的瞄勾,這也許看起來很奇怪费奸,代碼怎么可能是字符串?但是對于javascript來說进陡,這很平常愿阐。數(shù)據(jù)和代碼之間的區(qū)別是很模糊的。

//可以這樣創(chuàng)建函數(shù)
var fn = new Function("arg1", "arg2", "return arg1 * arg2;");
fn(3, 7); // return 3*7=21

這樣做的一個好處四濒,可以傳遞代碼給其他函數(shù)换况,也可以傳遞正則變量或者對象(因為代碼字面上只是對象而已)。

*傳遞函數(shù)作為回調(diào)

很容易把一個函數(shù)作為參數(shù)傳遞盗蟆。

function fn(arg1, arg2, callback){
 var num = Math.ceil(Math.random() * (arg1 - arg2) + arg2);
 callback(num);  //傳遞結(jié)果
}
 fn(10, 20, function(num){
 console.log("Callback called! Num: " + num);  //結(jié)果為10和20之間的隨機數(shù) 
});   

可能這樣做看起比較麻煩戈二,甚至有點愚蠢,為何不正常地返回結(jié)果喳资?但是當(dāng)遇上必須使用回調(diào)函數(shù)之時觉吭,你也許就不這樣認為了!
  別擋道,傳統(tǒng)函數(shù)以參數(shù)形式輸入數(shù)據(jù)仆邓,并且使用返回語句返回值鲜滩。理論上,在函數(shù)結(jié)尾處有一個return返回語句节值,結(jié)構(gòu)上就是:一個輸入點和一個輸出點徙硅。這比較容易理解,函數(shù)本質(zhì)上就是輸入和輸出之間實現(xiàn)過程的映射搞疗。
  但是嗓蘑,當(dāng)函數(shù)的實現(xiàn)過程非常漫長,你是選擇等待函數(shù)完成處理匿乃,還是使用回調(diào)函數(shù)進行異步處理呢桩皿?這種情況下,使用回調(diào)函數(shù)變得至關(guān)重要幢炸,例如:AJAX請求泄隔。若是使用回調(diào)函數(shù)進行處理,代碼就可以繼續(xù)進行其他任務(wù)宛徊,而無需空等佛嬉。實際開發(fā)中,經(jīng)常在javascript中使用異步調(diào)用闸天,甚至在這里強烈推薦使用巷燥!

*回調(diào)是什么?

看維基的 Callback_(computer_programming) 條目:

In computer programming, a callback is a reference to a piece of executable code that is passed as an argument to other code.

jQuery文檔How jQuery Works#Callback_and_Functio...條目:

A callback is a function that is passed as an argument to another function and is executed after its parent function has completed. The special thing about a callback is that functions that appear after the "parent" can execute before the callback executes. Another important thing to know is how to properly pass the callback. This is where I have often forgotten the proper syntax.

baidu百科:回調(diào)函數(shù)

回調(diào)函數(shù)就是一個通過函數(shù)指針調(diào)用的函數(shù)号枕。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個函數(shù)缰揪,當(dāng)這個指針被用為調(diào)用它所指向的函數(shù)時,我們就說這是回調(diào)函數(shù)葱淳《巯伲回調(diào)函數(shù)不是由該函數(shù)的實現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時由另外的一方調(diào)用的赞厕,用于對該事件或條件進行響應(yīng)艳狐。
*******(認真看)因此,回調(diào)本質(zhì)上是一種設(shè)計模式皿桑,并且jQuery(包括其他框架)的設(shè)計原則遵循了這個模式毫目。
在JavaScript中蔬啡,回調(diào)函數(shù)具體的定義為:函數(shù)A作為參數(shù)(函數(shù)引用)傳遞到另一個函數(shù)B中,并且這個函數(shù)B執(zhí)行函數(shù)A镀虐。我們就說函數(shù)A叫做回調(diào)函數(shù)箱蟆。如果沒有名稱(函數(shù)表達式),就叫做匿名回調(diào)函數(shù)刮便。
因此callback 不一定用于異步空猜,一般同步(阻塞)的場景下也經(jīng)常用到回調(diào),比如要求執(zhí)行某些操作后執(zhí)行回調(diào)函數(shù)恨旱。
例子
一個同步(阻塞)中使用回調(diào)的例子辈毯,目的是在func1代碼執(zhí)行完成后執(zhí)行func2。

var func1=function(callback){
  //do something.
  (callback && typeof(callback) === "function") && callback();
 }
  var func2=function(){ } 
  func1(func2);

異步j(luò)query.ajax回調(diào)的例子

   $.ajax({
                    type: "POST",
                    url: url,
                    data: {"key":JSON.stringify(),  } ,
                    success:function(data){
                       //success回調(diào)
                   },
                    error:function(data){
                   //error回調(diào)
                    }
                });

注意的是搜贤,ajax請求確實是異步的,不過這請求是由瀏覽器新開一個線程請求,當(dāng)請求的狀態(tài)變更時,如果先前已設(shè)置回調(diào),這異步線程就產(chǎn)生狀態(tài)變更事件放到 JavaScript引擎的處理隊列中等待處理谆沃。

下面貼上我今天寫的回調(diào)代碼~~~

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BlackWingJsCallBackFunctionTest</title>
</head>
<script type="text/javascript" src="../js/jquery-3.2.1.min.js"></script>
<body>
<button onClick=test1()>test1()</button>
<button onClick=test2()>test2()</button>
<button onClick=test2()>test3()</button>
</body>
<script language="JavaScript" type="text/javascript">
    var callbackF;
    var questionTest1="1+1";
    var questionTest2="what are you doing?";
    function asyn(question,callBack,type)
    {
      console.log("asyn:\t你好我是asyn,我知道了你的問題是"+question+",算好我告訴你")


      if(type==1)
      {

          console.log("asyn:\t你妹的1+1=2")
           answer=2;
      }else if(type==2)
      {
          console.log("asyn:\t我在等人請我?guī)兔?我可以做很多事情(很多情況下耗時操作)")
           answer="我在等人請我?guī)兔?我可以做很多事情(很多情況下耗時操作)"
      }
      if(typeof callBack=="function")
      {
          callBack(answer)
      }else {
          console.log("asyn:\tcallback不是function我沒法告訴他")
      }
    }
    function b(answer){
        console.log("b:\t我收到了你的答案是"+answer);
        callbackF();
    }
    function c(answer){
        console.log("c:\t我收到了你的答案是"+answer);
        callbackF();
    }
    function test1() {
        console.log("test1:\t你好asyn,幫我算個問題,算好了告訴b")
        asyn(questionTest1,b,1);
    }
    function test2() {
        console.log("test2:\t你好asyn,what are you doing?,請回答c")
        asyn(questionTest2,c,2);
    }
    function test3() {
        console.log("test3:\t你好asyn,我傳入去參數(shù)不是function");
        asyn("1+1","...",3)
    }
    $(function(){
        callbackF = function(){
            console.log("callbackF:\t我是回調(diào)函數(shù)callbackF");
        }
    });
</script>
</html>
</html>

點擊test1 執(zhí)行 function test1(){...} 運行結(jié)果如下圖


image.png

點擊test2 執(zhí)行 function test2(){...} 運行結(jié)果如下圖


image.png

點擊test3 注意這里的test3執(zhí)行的function 去調(diào)用asyn并沒有傳入function參數(shù) 所以也就會在
 if(typeof callBack=="function")
      {
          callBack(answer)
      }else {
          console.log("asyn:\tcallback不是function我沒法告訴他")
      }

這里執(zhí)行else 不會執(zhí)行回調(diào)了 效果如下圖
image.png

如有進一步討論的小伙伴請給我留言

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市仪芒,隨后出現(xiàn)的幾起案子管毙,更是在濱河造成了極大的恐慌,老刑警劉巖桌硫,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夭咬,死亡現(xiàn)場離奇詭異,居然都是意外死亡铆隘,警方通過查閱死者的電腦和手機卓舵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來膀钠,“玉大人掏湾,你說我怎么就攤上這事≈壮埃” “怎么了融击?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長雳窟。 經(jīng)常有香客問我尊浪,道長,這世上最難降的妖魔是什么封救? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任拇涤,我火速辦了婚禮,結(jié)果婚禮上誉结,老公的妹妹穿的比我還像新娘鹅士。我一直安慰自己,他們只是感情好惩坑,可當(dāng)我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布掉盅。 她就那樣靜靜地躺著也拜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪趾痘。 梳的紋絲不亂的頭發(fā)上慢哈,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天,我揣著相機與錄音扼脐,去河邊找鬼。 笑死奋刽,一個胖子當(dāng)著我的面吹牛瓦侮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播佣谐,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼肚吏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了狭魂?” 一聲冷哼從身側(cè)響起罚攀,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎雌澄,沒想到半個月后斋泄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡镐牺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年炫掐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片睬涧。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡募胃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出畦浓,到底是詐尸還是另有隱情痹束,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布讶请,位于F島的核電站祷嘶,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏夺溢。R本人自食惡果不足惜抹蚀,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望企垦。 院中可真熱鬧环壤,春花似錦、人聲如沸钞诡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至接箫,卻和暖如春攒读,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辛友。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工薄扁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人废累。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓邓梅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親邑滨。 傳聞我的和親對象是個殘疾皇子日缨,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容