js中的回調(diào)函數(shù)

大家好,我是IT修真院成都分院第09期學(xué)員励饵。今天分享的內(nèi)容是js中回調(diào)函數(shù)肿嘲?

1.背景介紹

在我們接觸ajax,與angularjs中的數(shù)據(jù)請(qǐng)求時(shí)次乓,我們總是聽到里面的回調(diào)函數(shù)吓歇,callback。我們?cè)谑褂玫倪^程中總感覺它是一個(gè)混淆的概念票腰,它仿佛是ajax請(qǐng)求后調(diào)用的那個(gè)函數(shù)城看,又感覺它是某一個(gè)函數(shù)的形參而已。在后面angular和promise的學(xué)習(xí)中杏慰,我們會(huì)遇到非常多的回調(diào)函數(shù)测柠,因此我們有必要弄清其中的概念

2.知識(shí)剖析

我們都知道js是單線程的炼鞠,這種設(shè)計(jì)模式給我們帶來(lái)了很多的方便之處,我們不需要考慮各個(gè)線程之間的通信轰胁,也不需要寫很多燒腦的代碼谒主,也就是說(shuō)js的引擎只能一件一件事的去完成和執(zhí)行相關(guān)的操作,所以所有需要執(zhí)行的事情都像排隊(duì)一樣赃阀,等待著被觸發(fā)和執(zhí)行霎肯,可是如果這樣的話,如果在隊(duì)列中有一件事情需要花費(fèi)很多的時(shí)間榛斯,那么后面的任務(wù)都將處于一種等待狀態(tài)观游,有時(shí)甚至?xí)霈F(xiàn)瀏覽器假死現(xiàn)象,例如其中有一件正在執(zhí)行的一個(gè)任務(wù)是一個(gè)死循環(huán)驮俗,那么會(huì)導(dǎo)致后續(xù)其他的任務(wù)無(wú)法正常執(zhí)行懂缕,所以js在同步機(jī)制的缺陷下設(shè)計(jì)出了異步模式

在異步執(zhí)行的模式下,每一個(gè)異步的任務(wù)都有其自己一個(gè)或著多個(gè)回調(diào)函數(shù)王凑,這樣當(dāng)前在執(zhí)行的異步任務(wù)執(zhí)行完之后搪柑,不會(huì)馬上執(zhí)行事件隊(duì)列中的下一項(xiàng)任務(wù),而是執(zhí)行它的回調(diào)函數(shù)荤崇,而下一項(xiàng)任務(wù)也不會(huì)等當(dāng)前這個(gè)回調(diào)函數(shù)執(zhí)行完拌屏,因?yàn)樗膊荒艽_定當(dāng)前的回調(diào)合適執(zhí)行完畢潮针,只要引它被觸發(fā)就會(huì)執(zhí)行

1.搞清楚異步和同步

1.早上起來(lái)不論你是先刷牙還是先洗臉术荤,都要等一個(gè)事情完畢后才能進(jìn)行下一項(xiàng),這就是一個(gè)同步的例子

2.然后刷牙的時(shí)候你也可以燒水喝 (不用等你刷完牙)這就是一個(gè)異步的例子

function a(){

console.log("執(zhí)行函數(shù)a");

setTimeout(function(){

console.log('執(zhí)行a的延遲函數(shù)')

},1000)

}

function b(){

console.log('執(zhí)行函數(shù)b')

}

a();

b();

? ? 調(diào)用 setTimeout 函數(shù)會(huì)在一個(gè)時(shí)間段過去后在隊(duì)列中添加一個(gè)消息每篷。這個(gè)時(shí)間段作為函數(shù)的第二個(gè)參數(shù)被傳入瓣戚。如果隊(duì)列中沒有其它消息,消息會(huì)被馬上處理焦读。但是子库,如果有其它消息,setTimeout 消息必須等待其它消息處理完矗晃。因此第二個(gè)參數(shù)僅僅表示最少的時(shí)間 而非確切的時(shí)間

var a=0;

function change() {

a=1;

}

function after(){

console.log(a);

}

change();

after();

2.回調(diào)函數(shù)到底是什么仑嗅?

A callback is a function that is passed as an argument to another function and is executed after its parent function has completed.

3.回調(diào)函數(shù)是怎么運(yùn)作的

因?yàn)楹瘮?shù)在Javascript中是第一類對(duì)象,我們像對(duì)待對(duì)象一樣對(duì)待函數(shù)张症,因此我們能像傳遞變量一樣傳遞函數(shù)仓技,在函數(shù)中返回函數(shù),在其他函數(shù)中使用函數(shù)俗他。當(dāng)我們將一個(gè)回調(diào)函數(shù)作為參數(shù)傳遞給另一個(gè)函數(shù)是脖捻,我們僅僅傳遞了函數(shù)定義。我們并沒有在參數(shù)中執(zhí)行函數(shù)兆衅。我們并不傳遞像我們平時(shí)執(zhí)行函數(shù)一樣帶有一對(duì)執(zhí)行小括號(hào)()的函數(shù)地沮。

? ? 人話:字面上理解下來(lái)就是嗜浮,回調(diào)就是一個(gè)函數(shù)的調(diào)用過程。那么就從理解這個(gè)調(diào)用過程開始吧摩疑。函數(shù)a有一個(gè)參數(shù)危融,這個(gè)參數(shù)是個(gè)函數(shù)b,當(dāng)函數(shù)a執(zhí)行完以后執(zhí)行函數(shù)b雷袋。那么這個(gè)過程就叫回調(diào)专挪。

這里必須清楚一點(diǎn):函數(shù)b是你以參數(shù)形式傳給函數(shù)a的,那么函數(shù)b就叫回調(diào)函數(shù)片排。

3寨腔、常見問題

1.為什么寫回調(diào)函數(shù)

2.回調(diào)函數(shù)一定要以參數(shù)形式傳過去嗎,我不可以直接在函數(shù)a里面調(diào)用函數(shù)b嗎率寡?

4迫卢、解決方案

function a(callback)

{

console.log("我是parent函數(shù)a!");

console.log("調(diào)用回調(diào)函數(shù)");

callback();

}

function b(){

console.log("我是回調(diào)函數(shù)b");

}

function c(){

console.log("我是回調(diào)函數(shù)c");

}

function test()

{

a(b);

a(c);

}

test();

如果你直接在函數(shù)a里調(diào)用的話冶共,那么這個(gè)回調(diào)函數(shù)就被限制死了乾蛤。但是使用函數(shù)做參數(shù)就有下面的好處:當(dāng)你a(b)的時(shí)候函數(shù)b就成了回調(diào)函數(shù),而你還可以a(c)這個(gè)時(shí)候捅僵,函數(shù)c就成了回調(diào)函數(shù)家卖。如果你寫成了function a(){...;b();}就失去了變量的靈活性。

啟示:函數(shù)在javascript中和數(shù)據(jù)一樣庙楚,可以賦值上荡,刪除,拷貝馒闷,自然也可以作為函數(shù)的參數(shù)

5.擴(kuò)展思考

回調(diào)函數(shù)與ES6中的promise

6.參考文獻(xiàn)

7酪捡、更多討論

問題1:能否利用回調(diào)函數(shù)避免angular?ajax異步請(qǐng)求延時(shí)導(dǎo)致的注入錯(cuò)誤

答:$http 請(qǐng)求時(shí)間太長(zhǎng),就會(huì)導(dǎo)致注入錯(cuò)誤

問題2:實(shí)現(xiàn)異步是js纳账,還是宿主瀏覽器逛薇?

答:JS的單線程是指一個(gè)瀏覽器進(jìn)程中只有一個(gè)JS的執(zhí)行線程,同一時(shí)刻內(nèi)只會(huì)有一段代碼在執(zhí)行(你可以使用IE的標(biāo)簽式瀏覽試試看效果疏虫,這時(shí)打開的多個(gè)頁(yè)面使用的都是同一個(gè)JS執(zhí)行線程永罚,如果其中一個(gè)頁(yè)面在執(zhí)行一個(gè)運(yùn)算量較大的function時(shí),其他窗口的JS就會(huì)停止工作)卧秘。

而異步機(jī)制是瀏覽器的兩個(gè)或以上常駐線程共同完成的呢袱,例如異步請(qǐng)求是由兩個(gè)常駐線程:JS執(zhí)行線程和事件觸發(fā)線程共同完成的,JS的執(zhí)行線程發(fā)起異步請(qǐng)求(這時(shí)瀏覽器會(huì)開一條新的HTTP請(qǐng)求線程來(lái)執(zhí)行請(qǐng)求斯议,這時(shí)JS的任務(wù)已完成产捞,繼續(xù)執(zhí)行線程隊(duì)列中剩下的其他任務(wù)),然后在未來(lái)的某一時(shí)刻事件觸發(fā)線程監(jiān)視到之前的發(fā)起的HTTP請(qǐng)求已完成哼御,它就會(huì)把完成事件插入到JS執(zhí)行隊(duì)列的尾部等待JS處理坯临。又例如定時(shí)觸發(fā)(settimeout和setinterval)是由瀏覽器的定時(shí)器線程執(zhí)行的定時(shí)計(jì)數(shù)焊唬,然后在定時(shí)時(shí)間把定時(shí)處理函數(shù)的執(zhí)行請(qǐng)求插入到JS執(zhí)行隊(duì)列的尾端(所以用這兩個(gè)函數(shù)的時(shí)候,實(shí)際的執(zhí)行時(shí)間是大于或等于指定時(shí)間的看靠,不保證能準(zhǔn)確定時(shí)的)赶促。

所以,所謂的JS的單線程和異步更多的應(yīng)該是屬于瀏覽器的行為挟炬,他們之間沒有沖突鸥滨,更不是同一種事物,沒有什么區(qū)別不區(qū)別的谤祖。

問題3:js每次只執(zhí)行一個(gè)任務(wù)婿滓,他是如何實(shí)現(xiàn)異步的?

答:見代碼

鳴謝

感謝大家觀看粥喜!

------------------------------------------------------------------------------------------------------------------------

技能樹.IT修真院

“我們相信人人都可以成為一個(gè)工程師凸主,現(xiàn)在開始,找個(gè)師兄额湘,帶你入門卿吐,掌控自己學(xué)習(xí)的節(jié)奏,學(xué)習(xí)的路上不再迷梅婊”嗡官。

這里是技能樹.IT修真院,成千上萬(wàn)的師兄在這里找到了自己的學(xué)習(xí)路線毯焕,學(xué)習(xí)透明化衍腥,成長(zhǎng)可見化,師兄1對(duì)1免費(fèi)指導(dǎo)芥丧〗衾快來(lái)與我一起學(xué)習(xí)吧 坊罢!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末续担,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子活孩,更是在濱河造成了極大的恐慌物遇,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件憾儒,死亡現(xiàn)場(chǎng)離奇詭異询兴,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)起趾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門诗舰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人训裆,你說(shuō)我怎么就攤上這事眶根∈癫” “怎么了?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵属百,是天一觀的道長(zhǎng)记劝。 經(jīng)常有香客問我,道長(zhǎng)族扰,這世上最難降的妖魔是什么厌丑? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮渔呵,結(jié)果婚禮上怒竿,老公的妹妹穿的比我還像新娘。我一直安慰自己扩氢,他們只是感情好愧口,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著类茂,像睡著了一般耍属。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上巩检,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天厚骗,我揣著相機(jī)與錄音,去河邊找鬼兢哭。 笑死领舰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的迟螺。 我是一名探鬼主播冲秽,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼矩父!你這毒婦竟也來(lái)了锉桑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤窍株,失蹤者是張志新(化名)和其女友劉穎民轴,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體球订,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡后裸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了冒滩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片微驶。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖开睡,靈堂內(nèi)的尸體忽然破棺而出因苹,到底是詐尸還是另有隱情较店,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布容燕,位于F島的核電站梁呈,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蘸秘。R本人自食惡果不足惜官卡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望醋虏。 院中可真熱鬧寻咒,春花似錦、人聲如沸颈嚼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)阻课。三九已至叫挟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間限煞,已是汗流浹背抹恳。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留署驻,地道東北人奋献。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像旺上,于是被迫代替她去往敵國(guó)和親瓶蚂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344