摘要:首先要知道的是,回調(diào)和異步不是同一個東西我以前認(rèn)為中每個回調(diào)函數(shù)都是異步處理的,實際上并不是,可以同步回調(diào),也可以異步回調(diào)例子說到,大家都在中遇到以下的例子這些代碼用了這么久,知道怎么用,但是可能對回調(diào)的概念并不是那么清晰再來個例子執(zhí)行函數(shù)
首先要知道的是,回調(diào)和異步不是同一個東西
我以前認(rèn)為js中每個回調(diào)函數(shù)都是異步處理的,實際上并不是,可以同步回調(diào),也可以異步回調(diào)
說到callback,大家都在javascript中遇到以下的例子
$("#id").on("click", function(){ //code }); $("#id").setTimeout(function(){ //code },1000);
這些代碼用了這么久,知道怎么用,但是可能對回調(diào)的概念并不是那么清晰
再來個例子
function a(callback) { alert("執(zhí)行parent函數(shù)a!"); alert("開始調(diào)用回調(diào)函數(shù)"); callback(); alert("結(jié)束回調(diào)函數(shù)"); } function b(){ alert("執(zhí)行回調(diào)函數(shù)b"); } function test() { a(b); a(function() { alert("執(zhí)行匿名回調(diào)函數(shù)"); }); } test();
執(zhí)行順序:
執(zhí)行parent函數(shù)a!
開始調(diào)用回調(diào)函數(shù)
執(zhí)行回調(diào)函數(shù)b
結(jié)束回調(diào)函數(shù)
執(zhí)行parent函數(shù)a!
開始調(diào)用回調(diào)函數(shù)
執(zhí)行匿名回調(diào)函數(shù)
結(jié)束回調(diào)函數(shù)
簡單的說,就是把一個函數(shù)作為形參進(jìn)行傳遞,上面的callback參數(shù)可以改為任意名字
callback 用 C++ 實現(xiàn) 不帶參數(shù)回調(diào)#include帶參數(shù)回調(diào)using namespace std; //定義回調(diào)函數(shù) void Print() { cout <<"Hello World! "; } //定義實現(xiàn)回調(diào)函數(shù)的"調(diào)用函數(shù)" void Call(void (*callback)()) { callback(); } //在main函數(shù)中實現(xiàn)函數(shù)回調(diào) int main(int argc,char* argv[]) { Call(Print); return 0; }
#include異步例子using namespace std; //定義帶參回調(diào)函數(shù) void Print(string s) { cout << s << endl; } //定義實現(xiàn)帶參回調(diào)函數(shù)的"調(diào)用函數(shù)" void Call(void (*callback)(string),string s) { callback(s); } //在main函數(shù)中實現(xiàn)帶參的函數(shù)回調(diào) int main(int argc,char* argv[]) { Call(Print,"Hello World!"); return 0; }
經(jīng)典例子
function a(){ console.log("執(zhí)行a"); setTimeout(function(){ console.log("setTimeout"); }, 1000); } function b(){ console.log("執(zhí)行b"); } a(); b();
執(zhí)行順序:
執(zhí)行a
執(zhí)行b
setTimeout (一秒后執(zhí)行)
都知道js是單線程的,所謂的單線程就是一次只能完成一個任務(wù),其任務(wù)的調(diào)度方式就是排隊,毫無疑問,這樣的效率是不高的,后面的任務(wù)必須等到前面的任務(wù)執(zhí)行完畢后才能執(zhí)行,如果有一個比較耗時的操作,比如http請求,文件io
其他語言遇到這種比較耗時的任務(wù)往往是開一個線程來處理,但js本身就是單線程的,js對這種任務(wù)的處理就是這個一個任務(wù)掛載起來,等耗時任務(wù)完成后再把回調(diào)函數(shù)添加到執(zhí)行隊列尾部
所以,在剛剛這個例子中,即使把延遲時間設(shè)置為0,也是一樣的結(jié)果
本文同步更新我的個人博客https://blog.yjqing.xin/js-ca...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/99211.html
摘要:同步與異步以上為同步代碼,函數(shù)必須等函數(shù)執(zhí)行完畢后才能執(zhí)行。異步回調(diào)產(chǎn)生的結(jié)果就是,函數(shù)的調(diào)用并不直接返回結(jié)果,而往往是交給回調(diào)函數(shù)進(jìn)行異步處理。 同步與異步: function a(){} function b(){} a(); b(); 以上為同步代碼,函數(shù)b必須等函數(shù)a執(zhí)行完畢后才能執(zhí)行。 function a(){ ...
摘要:而是在調(diào)用發(fā)出后,被調(diào)用者通過狀態(tài)通知來通知調(diào)用者,或通過回調(diào)函數(shù)處理這個調(diào)用。請求程序發(fā)出請求,從服務(wù)器端獲取數(shù)據(jù),并設(shè)置了回調(diào)函數(shù)。然后,瀏覽器會設(shè)置偵聽來自網(wǎng)絡(luò)的響應(yīng),拿到數(shù)據(jù)后,將該回調(diào)函數(shù)插入到事件循環(huán)。 并發(fā)與并行 并發(fā)是指兩個或多個事件鏈隨時間發(fā)展交替執(zhí)行,以至于從更高的層次來看,就像是同時運(yùn)行(但在任意時刻只處理一個事件) 并發(fā)的關(guān)鍵是你有處理多個任務(wù)的能力,不一定同...
摘要:引擎線程也稱為內(nèi)核,負(fù)責(zé)處理腳本程序例如引擎引擎線程負(fù)責(zé)解析腳本,運(yùn)行代碼。對象代表一個未完成但預(yù)計將來會完成的操作。注意一旦新建就會立即執(zhí)行它屬于,無法取消。 寫在前面: 第一遍學(xué)Promise時, 只是大概過了一遍, 感覺學(xué)的不夠深入, 這一篇算是對之前的一個總結(jié)吧. Promise在ES6中也屬于一個較難理解的一部分; 所以在學(xué)習(xí)一個比較難理解的知識點(diǎn)時, 我們可以圍繞這個知識點(diǎn)...
摘要:單線程異步非阻塞然后,這又牽扯到了事件循環(huán)消息隊列,還有微任務(wù)宏任務(wù)這些。此步的位置不確定某個時刻后,定時器觸發(fā)線程通知事件觸發(fā)線程,事件觸發(fā)線程將回調(diào)函數(shù)加入消息隊列隊尾,等待引擎線程執(zhí)行。 前言 Philip Roberts 在演講 great talk at JSConf on the event loop 中說:要是用一句話來形容 JavaScript,我可能會這樣: Java...
摘要:由于引擎同一時間只執(zhí)行一段代碼這是由單線程的性質(zhì)決定的,所以每個代碼塊阻塞了其它異步事件的進(jìn)行。這意味著瀏覽器將等待著一個新的異步事件發(fā)生。異步的任務(wù)執(zhí)行的順序是不固定的,主要看返回的速度。 我們經(jīng)常說JS是單線程的,比如node.js研討會上大家都說JS的特色之一是單線程的,這樣使JS更簡單明了,可是大家真的理解所謂JS的單線程機(jī)制嗎?單線程時,基于事件的異步機(jī)制又該當(dāng)如何,這些知識...
閱讀 877·2021-11-24 09:38
閱讀 1102·2021-10-08 10:05
閱讀 2598·2021-09-10 11:21
閱讀 2814·2019-08-30 15:53
閱讀 1842·2019-08-30 15:52
閱讀 1981·2019-08-29 12:17
閱讀 3431·2019-08-29 11:21
閱讀 1623·2019-08-26 12:17