JS中的回調(diào)函數(shù)(callback)講解
1.什么是回調(diào)函數(shù)(callback)呢?
把函數(shù)當(dāng)作一個(gè)參數(shù)傳到另外一個(gè)函數(shù)中,當(dāng)需要用這個(gè)函數(shù)是,再回調(diào)運(yùn)行()這個(gè)函數(shù).
回調(diào)函數(shù)是一段可執(zhí)行的代碼段,它作為一個(gè)參數(shù)傳遞給其他的代碼,其作用是在需要的時(shí)候方便調(diào)用這段(回調(diào)函數(shù))代碼。(作為參數(shù)傳遞到另外一個(gè)函數(shù)中,這個(gè)作為參數(shù)的函數(shù)就是回調(diào)函數(shù))
理解:函數(shù)可以作為一個(gè)參數(shù)傳遞到另外一個(gè)函數(shù)中。
<script> function add(num1, num2, callback) { var sum = num1 + num2; callback(sum); } function print(num) { console.log(num); } add(1, 2, print); //3 </script>
分析:add(1, 2, print);中,函數(shù)print作為一個(gè)參數(shù)傳入到add函數(shù)中,但并不是馬上起作用,而是var sum = num1 + num2;運(yùn)行完之后需要打印輸出sum的時(shí)候才會(huì)調(diào)用這個(gè)函數(shù)。(這個(gè)作為參數(shù)傳遞到另外一個(gè)函數(shù)中,這個(gè)作為參數(shù)的函數(shù)就是回調(diào)函數(shù).
匿名回調(diào)函數(shù):
<script> function add(num1, num2, callback) { var sum = num1 + num2; callback(sum); } add(1, 2, function (sum) { console.log(sum); //=>3 }); </script>
2.回調(diào)函數(shù)有哪些特點(diǎn)?
1.不會(huì)立即執(zhí)行
回調(diào)函數(shù)作為參數(shù)傳遞給一個(gè)函數(shù)的時(shí)候,傳遞的只是函數(shù)的定義并不會(huì)立即執(zhí)行。和普通的函數(shù)一樣,回調(diào)函數(shù)在調(diào)用函數(shù)數(shù)中也要通過(guò)()
運(yùn)算符調(diào)用才會(huì)執(zhí)行。
2.回調(diào)函數(shù)是一個(gè)閉包
回調(diào)函數(shù)是一個(gè)閉包,也就是說(shuō)它能訪問(wèn)到其外層定義的變量。
3.執(zhí)行前類(lèi)型判斷
在執(zhí)行回調(diào)函數(shù)前最好確認(rèn)其是一個(gè)函數(shù)。
<script> function add(num1, num2, callback) { var sum = num1 + num2; //判定callback接收到的數(shù)據(jù)是一個(gè)函數(shù) if (typeof callback === 'function') { //callback是一個(gè)函數(shù),才能當(dāng)回調(diào)函數(shù)使用 callback(sum); } } </script>
3.回調(diào)函數(shù)中this的指向問(wèn)題
注意在回調(diào)函數(shù)調(diào)用時(shí)this的執(zhí)行上下文并不是回調(diào)函數(shù)定義時(shí)的那個(gè)上下文,而是調(diào)用它的函數(shù)所在的上下文。
舉例:
<script> function createData(callback){ callback(); } var obj ={ data:100, tool:function(){ createData(function(n){ console.log(this,1111); //window 1111 }) } } obj.tool(); </script>
分析:this指向是 離它最近的或者嵌套級(jí)別的 function/方法的調(diào)用者,這里離它最近的function是
function(n),會(huì)回到上面的callback()中,這時(shí)候調(diào)用者就不是obj而是window。
解決回調(diào)函數(shù)this指向的方法1:箭頭函數(shù)
回調(diào)函數(shù)(若回調(diào)函數(shù)是普通函數(shù)時(shí))當(dāng)參數(shù)傳入另外的函數(shù)時(shí),若不知道這個(gè)函數(shù)內(nèi)部怎么調(diào)用回調(diào)函數(shù),就會(huì)出現(xiàn)回調(diào)函數(shù)中的this指向不明確的問(wèn)題(就比如上面例子中this指向的不是obj而是window)。所以 把箭頭函數(shù)當(dāng)回調(diào)函數(shù),然后作為參數(shù)傳入另外的函數(shù)中就不會(huì)出現(xiàn)this指向不明的問(wèn)題。
<script> function createData(callback){ callback(); } var obj ={ data:100, tool:function(){ createData((n)=>{ this.data = n; }) } } obj.tool(); console.log(obj.data); </script>
分析:回調(diào)函數(shù)用箭頭函數(shù)寫(xiě)之后,this指向很明確,就是 離它最近的或者嵌套級(jí)別的 function/方法的調(diào)用者,所以這里是 obj 。
解決回調(diào)函數(shù)this指向的方法2:var self = this;
<script> function createData(callback){ callback(999); } var obj ={ data:100, tool:function(){ var self = this; //這里的this指向obj,然后當(dāng)一個(gè)變量取用 createData(function(n){ self.data = n; }) } } obj.tool(); console.log(obj.data); </script>
4.為什么要用到回調(diào)函數(shù)?
有一個(gè)非常重要的原因 —— JavaScript 是事件驅(qū)動(dòng)的語(yǔ)言。這意味著,JavaScript 不會(huì)因?yàn)橐却粋€(gè)響應(yīng)而停止當(dāng)前運(yùn)行,而是在監(jiān)聽(tīng)其他事件時(shí)繼續(xù)執(zhí)行。來(lái)看一個(gè)基本的例子:
<script> function first() { console.log(1); } function second() { console.log(2); } first(); second(); </script>
分析:正如你所料,first
函數(shù)首先被執(zhí)行,隨后 second
被執(zhí)行 —— 控制臺(tái)輸出:1 2
但如果函數(shù) first
包含某種不能立即執(zhí)行的代碼會(huì)如何呢?例如我們必須發(fā)送請(qǐng)求然后等待響應(yīng)的 API 請(qǐng)求?為了模擬這種狀況,我們將使用 setTimeout
,它是一個(gè)在一段時(shí)間之后調(diào)用函數(shù)的 JavaScript 函數(shù)。我們將函數(shù)延遲 500 毫秒來(lái)模擬一個(gè) API 請(qǐng)求,新代碼長(zhǎng)這樣:
<script> function first() { // 模擬代碼延遲 setTimeout(function () { //所以function(){console.log(1)}是回調(diào)函數(shù) console.log(1); }, 500); } function second() { console.log(2); } first(); second(); </script>
分析:這里 function(){console.log(1)}函數(shù)當(dāng)作一個(gè)參數(shù)傳入setTimeout函數(shù)中,因?yàn)閟etTimeout是官方提供得一個(gè)函數(shù),里面有很多復(fù)雜的業(yè)務(wù)程序,所以函數(shù) function(){console.log(1)}傳入后,不一定馬上運(yùn)行,要setTimeout里面要運(yùn)行到function(){console.log(1)}時(shí)才會(huì)運(yùn)行該函數(shù)參數(shù),那是不是整個(gè)程序就一直等setTimeout運(yùn)行?不是的?。。?/p>
整個(gè)程序運(yùn)行結(jié)果為: 2 1 ,并不是原先的1 2 .即使我們首先調(diào)用了 first()
函數(shù),我們記錄的輸出結(jié)果卻在 second()
函數(shù)之后。
這不是 JavaScript 沒(méi)有按照我們想要的順序執(zhí)行函數(shù)的問(wèn)題,而是 JavaScript 在繼續(xù)向下執(zhí)行 second()
之前沒(méi)有等待 first()
響應(yīng)的問(wèn)題。回調(diào)正是確保一段代碼執(zhí)行完畢之后再執(zhí)行另一段代碼的方式。
5.回調(diào)函數(shù)和異步操作的關(guān)系是什么?回調(diào)函數(shù)是異步么?
定義:回調(diào)函數(shù)被認(rèn)為是一種高級(jí)函數(shù),一種被作為參數(shù)傳遞給另一個(gè)函數(shù)的高級(jí)函數(shù)?;卣{(diào)函數(shù)的本質(zhì)是一種模式(一種解決常見(jiàn)問(wèn)題的模式),因此回調(diào)函數(shù)也被稱(chēng)為回調(diào)模式。
簡(jiǎn)而言之:一個(gè)函數(shù)在另一個(gè)函數(shù)中被調(diào)用。而且可以當(dāng)參數(shù)傳給其他函數(shù)。
所以: 回調(diào)函數(shù)和異步操作的關(guān)系是沒(méi)有關(guān)系?。?!
那為什么很多的異步操作都有回填函數(shù)????
問(wèn):你所知道的異步操作,是回調(diào)的作用么??? 并不是。
回調(diào):更多的可以理解為一種業(yè)務(wù)邏輯把 異步編程:JS代碼的執(zhí)行順序
簡(jiǎn)單理解:callback 顧名思義 打電話回來(lái)的意思
eg1:你點(diǎn)外賣(mài),剛好你要吃的食物沒(méi)有了,于是你在店老板那里留下了你的電話,過(guò)了幾天店里有了,店員就打了你的電話,然后你接到電話后就跑到店里買(mǎi)了。在這個(gè)例子里,你的電話號(hào)碼就叫回調(diào)函數(shù),你把電話留給店員就叫登記回調(diào)函數(shù),店里后來(lái)有貨了叫做觸發(fā)了回調(diào)關(guān)聯(lián)的事件,店員給你打電話叫做調(diào)用回調(diào)函數(shù),你到店里去取貨叫做響應(yīng)回調(diào)事件。
eg2:再比如,你發(fā)送一個(gè)axios 請(qǐng)求,請(qǐng)求成功之后,觸發(fā)成功的回調(diào)函數(shù),請(qǐng)求失敗觸發(fā)失敗的回調(diào)函數(shù)。這里面的回調(diào)函數(shù)更像是一個(gè)工具,后臺(tái)通過(guò)這個(gè)工具告訴你,你成功了抑或是失敗了。這里面的所有異步操作都和回調(diào)沒(méi)關(guān)系,真正的異步是then方法。
到此這篇關(guān)于JS中的 回調(diào)函數(shù)(callback)的文章就介紹到這了,更多相關(guān)js 回調(diào)函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用postMesssage()實(shí)現(xiàn)iframe跨域頁(yè)面間的信息傳遞
這篇文章主要介紹了使用postMesssage()實(shí)現(xiàn)iframe跨域頁(yè)面間的信息傳遞 的相關(guān)資料,需要的朋友可以參考下2016-03-03CodeMirror2 IE7/IE8 下面未知運(yùn)行時(shí)錯(cuò)誤的解決方法
最近用CodeMirror2作后臺(tái)的模板編輯器,在IE9、Firefox下面沒(méi)有問(wèn)題。到了IE7、IE8下面,textarea里面的代碼就顯示不出來(lái)了。搜索了好多,終于找到原因2012-03-03微信小程序?qū)崿F(xiàn)自定義modal彈窗封裝的方法
這篇文章主要介紹了小程序自定義modal彈窗封裝實(shí)現(xiàn)方法,本文通過(guò)實(shí)例代碼相結(jié)合的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下2018-06-06JavaScript新手必看之var在for循環(huán)中的坑
var這個(gè)關(guān)鍵字在JS當(dāng)中是相當(dāng)常用的,但同時(shí)配合到for循環(huán)的話會(huì)出現(xiàn)不符合預(yù)期的運(yùn)行結(jié)果,所以本文就來(lái)為大家講講如何避免這種情況的出現(xiàn)2023-05-05Javascript Request獲取請(qǐng)求參數(shù)如何實(shí)現(xiàn)
使用Javascript Request獲取參數(shù)的時(shí)候總是提示出錯(cuò),本文為此問(wèn)題提供詳細(xì)的解決方案,需要了解的朋友可以參考下2012-11-11