久久99久久人婷婷精品综合_超碰aⅴ人人做人人爽欧美_亚洲电影第三页_日韩欧美一中文字暮专区_波多野结衣的一区二区三区_婷婷在线播放_人人视频精品_国产精品日韩精品欧美精品_亚洲免费黄色_欧美性猛交xxxxxxxx

怎么理解回調函數

這篇文章主要介紹“怎么理解回調函數”,在日常操作中,相信很多人在怎么理解回調函數問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么理解回調函數”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

成都創新互聯于2013年成立,是專業互聯網技術服務公司,擁有項目網站設計制作、成都做網站網站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元微山做網站,已為上家服務,為微山各地企業和個人服務,聯系電話:18980820575

一切要從這樣的需求說起

假設你們公司要開發下一代國民App“明日油條”,一款主打解決國民早餐問題的App,為了加快開發進度,這款應用由A小組和B小組協同開發。

其中有一個核心模塊由A小組開發然后供B小組調用,這個核心模塊被封裝成了一個函數,這個函數就叫make_youtiao()。

如果make_youtiao()這個函數執行的很快并可以立即返回,那么B小組的同學只需要:

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. 調用make_youtiao()

  3. 等待該函數執行完成

  4. 該函數執行完后繼續后續流程

從程序執行的角度看這個過程是這樣的:

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. 保存當前被執行函數的上下文

  3. 開始執行make_youtiao()這個函數

  4. make_youtiao()執行完后,控制轉回到調用函數中

怎么理解回調函數

如果世界上所有的函數都像make_youtiao()這么簡單,那么程序員大概率就要失業了,還好程序的世界是復雜的,這樣程序員才有了存在的價值。

現實并不容易

現實中make_youtiao()這個函數需要處理的數據非常龐大,假設有10000個,那么make_youtiao(10000)不會立刻返回,而是可能需要10分鐘才執行完成并返回。

這時你該怎么辦呢?想一想這個問題。

可能有的同學會問,和剛才一樣直接調用不可以嗎,這樣多簡單。

是的,這樣做沒有問題,但就像愛因斯坦說的那樣“一切都應該盡可能簡單,但是不能過于簡單”。

想一想直接調用會有什么問題?

顯然直接調用的話,那么調用線程會被阻塞暫停,在等待10分鐘后才能繼續運行。在這10分鐘內該線程不會被操作系統分配CPU,也就是說該線程得不到任何推進。

這并不是一種高效的做法。

沒有一個程序員想死盯著屏幕10分鐘后才能得到結果。

那么有沒有一種更加高效的做法呢?

想一想我們上一篇中那個一直盯著你寫代碼的老板(見《從小白到高手,你需要理解同步與異步》),我們已經知道了這種一直等待直到另一個任務完成的模式叫做同步。

如果你是老板的話你會什么都不干一直盯著員工寫代碼嗎?因此一種更好的做法是程序員在代碼的時候老板該干啥干啥,程序員寫完后自然會通知老板,這樣老板和程序員都不需要相互等待,這種模式被稱為異步。

回到我們的主題,這里一種更好的方式是調用make_youtiao()這個函數后不再等待這個函數執行完成,而是直接返回繼續后續流程,這樣A小組的程序就可以和make_youtiao()這個函數同時進行了,就像這樣:

怎么理解回調函數

在這種情況下,回調(callback)就必須出場了。

為什么我們需要回調callback

有的同學可能還沒有明白為什么在這種情況下需要回調,別著急,我們慢慢講。

假設我們“明日油條”App代碼第一版是這樣寫的:

make_youtiao(10000); sell();

可以看到這是最簡單的寫法,意思很簡單,制作好油條后賣出去。

怎么理解回調函數

我們已經知道了由于make_youtiao(10000)這個函數10分鐘才能返回,你不想一直死盯著屏幕10分鐘等待結果,那么一種更好的方法是讓make_youtiao()這個函數知道制作完油條后該干什么,即,更好的調用make_youtiao的方式是這樣的:“制作10000個油條,炸好后賣出去”,因此調用make_youtiao就變出這樣了:

make_youtiao(10000, sell);

看到了吧,現在make_youtiao這個函數多了一個參數,除了指定制作油條的數量外還可以指定制作好后該干什么,第二個被make_youtiao這個函數調用的函數就叫回調,callback。

現在你應該看出來了吧,雖然sell函數是你定義的,但是這個函數卻是被其它模塊調用執行的,就像這樣:

怎么理解回調函數

make_youtiao這個函數是怎么實現的呢,很簡單:

void make_youtiao(int num, func call_back) {     // 制作油條     call_back(); //執行回調  }

這樣你就不用死盯著屏幕了,因為你把make_youtiao這個函數執行完后該做的任務交代給make_youtiao這個函數了,該函數制作完油條后知道該干些什么,這樣就解放了你的程序。

有的同學可能還是有疑問,為什么編寫make_youtiao這個小組不直接定義sell函數然后調用呢?

不要忘了明日油條這個App是由A小組和B小組同時開發的,A小組在編寫make_youtiao時怎么知道B小組要怎么用這個模塊,假設A小組真的自己定義sell函數就會這樣寫:

void make_youtiao(int num) {     real_make_youtiao(num);     sell(); //執行回調  }

同時A小組設計的模塊非常好用,這時C小組也想用這個模塊,然而C小組的需求是制作完油條后放到倉庫而不是不是直接賣掉,要滿足這一需求那么A小組該怎么寫呢?

void make_youtiao(int num) {     real_make_youtiao(num);          if (Team_B) {        sell(); // 執行回調     } else if (Team_D) {        store(); // 放到倉庫     } }

故事還沒完,假設這時D小組又想使用呢,難道還要接著添加if  else嗎?這樣的話A小組的同學只需要維護make_youtiao這個函數就能做到工作量飽滿了,顯然這是一種非常糟糕的設計。

所以你會看到,制作完油條后接下來該做什么不是實現make_youtiao的A小組該關心的事情,很明顯只有調用make_youtiao這個函數的使用方才知道。

因此make_youtiao的A小組完全可以通過回調函數將接下來該干什么交給調用方實現,A小組的同學只需要針對回調函數這一抽象概念進行編程就好了,這樣調用方在制作完油條后不管是賣掉、放到庫存還是自己吃掉等等想做什么都可以,A小組的make_youtiao函數根本不用做任何改動,因為A小組是針對回調函數這一抽象概念來編程的。

以上就是回調函數的作用,當然這也是針對抽象而不是具體實現進行編程這一思想的威力所在。面向對象中的多態本質上就是讓你用來針對抽象而不是針對實現來編程的。

異步回調

故事到這里還沒有結束。

在上面的示例中,雖然我們使用了回調這一概念,也就是調用方實現回調函數然后再將該函數當做參數傳遞給其它模塊調用。

但是,這里依然有一個問題,那就是make_youtiao函數的調用方式依然是同步的,關于同步異步請,也就是說調用方是這樣實現的:

make_youtiao(10000, sell); // make_youtiao函數返回前什么都做不了

 怎么理解回調函數

我們可以看到,調用方必須等待make_youtiao函數返回后才可以繼續后續流程,我們再來看下make_youtiao函數的實現:

void make_youtiao(int num, func call_back) {     real_make_youtiao(num);     call_back(); //執行回調  }

看到了吧,由于我們要制作10000個油條,make_youtiao函數執行完需要10分鐘,也就是說即便我們使用了回調,調用方完全不需要關心制作完油條后的后續流程,但是調用方依然會被阻塞10分鐘,這就是同步調用的問題所在。

如果你真的理解了上一節的話應該能想到一種更好的方法了。

沒錯,那就是異步調用。

反正制作完油條后的后續流程并不是調用方該關心的,也就是說調用方并不關心make_youtiao這一函數的返回值,那么一種更好的方式是:把制作油條的這一任務放到另一個線程(進程)、甚至另一臺機器上。

如果用線程實現的話,那么make_youtiao就是這樣實現了:

void make_youtiao(int num, func call_back) {     // 在新的線程中執行處理邏輯     create_thread(real_make_youtiao,                   num,                   call_back); }

 怎么理解回調函數

看到了吧,這時當我們調用make_youtiao時就會立刻返回,即使油條還沒有真正開始制作,而調用方也完全無需等待制作油條的過程,可以立刻執行后流程:

make_youtiao(10000, sell); // 立刻返回 // 執行后續流程

這時調用方的后續流程可以和制作油條同時進行,這就是函數的異步調用,當然這也是異步的高效之處。

新的編程思維模式

讓我們再來仔細的看一下這個過程。

程序員最熟悉的思維模式是這樣的:

  • 調用某個函數,獲取結果

  • 處理獲取到的結果

res = request(); handle(res);

這就是函數的同步調用,只有request()函數返回拿到結果后,才能調用handle函數進行處理,request函數返回前我們必須等待,這就是同步調用,其控制流是這樣的:

怎么理解回調函數

但是如果我們想更加高效的話,那么就需要異步調用了,我們不去直接調用handle函數,而是作為參數傳遞給request:

request(handle);

我們根本就不關心request什么時候真正的獲取的結果,這是request該關心的事情,我們只需要把獲取到結果后該怎么處理告訴request就可以了,因此request函數可以立刻返回,真的獲取結果的處理可能是在另一個線程、進程、甚至另一臺機器上完成。

這就是異步調用,其控制流是這樣的:

怎么理解回調函數

從編程思維上看,異步調用和同步有很大的差別,如果我們把處理流程當做一個任務來的話,那么同步下整個任務都是我們來實現的,但是異步情況下任務的處理流程被分為了兩部分:

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. 第一部分是我們來處理的,也就是調用request之前的部分

  3. 第二部分不是我們處理的,而是在其它線程、進程、甚至另一個機器上處理的。

我們可以看到由于任務被分成了兩部分,第二部分的調用不在我們的掌控范圍內,同時只有調用方才知道該做什么,因此在這種情況下回調函數就是一種必要的機制了。

也就是說回調函數的本質就是“只有我們才知道做些什么,但是我們并不清楚什么時候去做這些,只有其它模塊才知道,因此我們必須把我們知道的封裝成回調函數告訴其它模塊”。

現在你應該能看出異步回調這種編程思維模式和同步的差異了吧。

接下來我們給回調一個較為學術的定義

正式定義

在計算機科學中,回調函數是指一段以參數的形式傳遞給其它代碼的可執行代碼。

這就是回調函數的定義了。

回調函數就是一個函數,和其它函數沒有任何區別。

注意,回調函數是一種軟件設計上的概念,和某個編程語言沒有關系,幾乎所有的編程語言都能實現回調函數。

對于一般的函數來說,我們自己編寫的函數會在自己的程序內部調用,也就是說函數的編寫方是我們自己,調用方也是我們自己。

但回調函數不是這樣的,雖然函數編寫方是我們自己,但是函數調用方不是我們,而是我們引用的其它模塊,也就是第三方庫,我們調用第三方庫中的函數,并把回調函數傳遞給第三方庫,第三方庫中的函數調用我們編寫的回調函數,如圖所示:

怎么理解回調函數

而之所以需要給第三方庫指定回調函數,是因為第三方庫的編寫者并不清楚在某些特定節點,比如我們舉的例子油條制作完成、接收到網絡數據、文件讀取完成等之后該做什么,這些只有庫的使用方才知道,因此第三方庫的編寫者無法針對具體的實現來寫代碼,而只能對外提供一個回調函數,庫的使用方來實現該函數,第三方庫在特定的節點調用該回調函數就可以了。

另一點值得注意的是,從圖中我們可以看出回調函數和我們的主程序位于同一層中,我們只負責編寫該回調函數,但并不是我們來調用的。

最后值得注意的一點就是回調函數被調用的時間節點,回調函數只在某些特定的節點被調用,就像上面說的油條制作完成、接收到網絡數據、文件讀取完成等,這些都是事件,也就是event,本質上我們編寫的回調函數就是用來處理event的,因此從這個角度看回調函數不過就是event  handler,因此回調函數天然適用于事件驅動編程event-driven,我們將會在后續文章中再次回到這一主題。

回調的類型

我們已經知道有兩種類型的回調,這兩種類型的回調區別在于回調函數被調用的時機。

注意,接下來會用到同步和異步的概念,對這兩個概念不熟悉的同學可以參考上一盤文章《從小白到高手,你需要理解同步和異步》。

同步回調

這種回調就是通常所說的同步回調synchronous callbacks、也有的將其稱為阻塞式回調blocking  callbacks,或者什么修飾都沒有,就是回調,callback,這是我們最為熟悉的回調方式。

當我們調用某個函數A并以參數的形式傳入回調函數后,在A返回之前回調函數會被執行,也就是說我們的主程序會等待回調函數執行完成,這就是所謂的同步回調。

怎么理解回調函數

有同步回調就有異步回調。

異步回調

不同于同步回調,  當我們調用某個函數A并以參數的形式傳入回調函數后,A函數會立刻返回,也就是說函數A并不會阻塞我們的主程序,一段時間后回調函數開始被執行,此時我們的主程序可能在忙其它任務,回調函數的執行和我們主程序的運行同時進行。

既然我們的主程序和回調函數的執行可以同時發生,因此一般情況下,主程序和回調函數的執行位于不同的線程或者進程中。

怎么理解回調函數

這就是所謂的異步回調,asynchronous callbacks,也有的資料將其稱為deferred callbacks  ,名字很形象,延遲回調。

從上面這兩張圖中我們也可以看到,異步回調要比同步回調更能充分的利用機器資源,原因就在于在同步模式下主程序會“偷懶”,因為調用其它函數被阻塞而暫停運行,但是異步調用不存在這個問題,主程序會一直運行下去。

因此,異步回調更常見于I/O操作,天然適用于Web服務這種高并發場景。

回調對應的編程思維模式

讓我們用簡單的幾句話來總結一下回調下與常規編程思維模式的不同。假設我們想處理某項任務,這項任務需要依賴某項服務S,我們可以將任務的處理分為兩部分,調用服務S前的部分PA,和調用服務S后的部分PB。在常規模式下,PA和PB都是服務調用方來執行的,也就是我們自己來執行PA部分,等待服務S返回后再執行PB部分。但在回調這種方式下就不一樣了。在這種情況下,我們自己來執行PA部分,然后告訴服務S:“等你完成服務后執行PB部分”。因此我們可以看到,現在一項任務是由不同的模塊來協作完成的。即:常規模式:調用完S服務后后我去執行X任務,回調模式:調用完S服務后你接著再去執行X任務,其中X是服務調用方制定的,區別在于誰來執行。

為什么異步回調越來越重要

在同步模式下,服務調用方會因服務執行而被阻塞暫停執行,這會導致整個線程被阻塞,因此這種編程方式天然不適用于高并發動輒幾萬幾十萬的并發連接場景,針對高并發這一場景,異步其實是更加高效的,原因很簡單,你不需要在原地等待,因此從而更好的利用機器資源,而回調函數又是異步下不可或缺的一種機制。

回調地獄,callback hell

有的同學可能認為有了異步回調這種機制應付起一切高并發場景就可以高枕無憂了。實際上在計算機科學中還沒有任何一種可以橫掃一切包治百病的技術,現在沒有,在可預見的將來也不會有,一切都是妥協的結果。那么異步回調這種機制有什么問題呢?實際上我們已經看到了,異步回調這種機制和程序員最熟悉的同步模式不一樣,在可理解性上比不過同步,而如果業務邏輯相對復雜,比如我們處理某項任務時不止需要調用一項服務,而是幾項甚至十幾項,如果這些服務調用都采用異步回調的方式來處理的話,那么很有可能我們就陷入回調地獄中。舉個例子,假設處理某項任務我們需要調用四個服務,每一個服務都需要依賴上一個服務的結果,如果用同步方式來實現的話可能是這樣的:a  = GetServiceA();

b = GetServiceB(a);  c = GetServiceC(b);  d = GetServiceD(c);

代碼很清晰,很容易理解有沒有。我們知道異步回調的方式會更加高效,那么使用異步回調的方式來寫將會是什么樣的呢?GetServiceA(function(a){

GetServiceB(a, function(b){  GetServiceC(b, function(c){  GetServiceD(c, function(d) {  ....  });  });  });

我想不需要再強調什么了吧,你覺得這兩種寫法哪個更容易理解,代碼更容易維護呢?博主有幸曾經維護過這種類型的代碼,不得不說每次增加新功能的時候恨不得自己化為兩個分身,一個不得不去重讀一邊代碼;另一個在一旁罵自己為什么當初選擇維護這個項目。異步回調代碼稍不留意就會跌到回調陷阱中,那么有沒有一種更好的辦法既能結合異步回調的高效又能結合同步編碼的簡單易讀呢?幸運的是,答案是肯定的,我們會在后續文章中詳細講解這一技術。

到此,關于“怎么理解回調函數”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注創新互聯網站,小編會繼續努力為大家帶來更多實用的文章!

分享標題:怎么理解回調函數
路徑分享:http://www.js-pz168.com/article6/gppoig.html

成都網站建設公司_創新互聯,為您提供移動網站建設App開發動態網站電子商務外貿建站標簽優化

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

h5響應式網站建設
久久99久久人婷婷精品综合_超碰aⅴ人人做人人爽欧美_亚洲电影第三页_日韩欧美一中文字暮专区_波多野结衣的一区二区三区_婷婷在线播放_人人视频精品_国产精品日韩精品欧美精品_亚洲免费黄色_欧美性猛交xxxxxxxx
欧美一二三区在线观看| 日韩精品一区二区三区四区视频| 日韩一区二区免费电影| 日韩精品一区二区三区视频| 欧美不卡一二三| 亚洲精品在线观看视频| 久久综合狠狠综合久久激情 | 欧美一区二区三区啪啪| 欧美一区少妇| 欧美一区免费视频| 牛人盗摄一区二区三区视频| 97久久超碰精品国产| 天天色 色综合| 国产日韩三级在线| 91成人免费网站| 国产欧美亚洲日本| 精品一区二区免费视频| 亚洲欧美日韩在线| 国产精品美女久久久久久久久久久 | 欧美三级电影在线看| 精品毛片久久久久久| 国产精品一区二区av| 欧美性大战久久久久| 欧美在线观看视频一区二区三区| www.久久草| 91国偷自产一区二区三区成为亚洲经典 | 午夜一区二区三区| 欧美变态tickling挠脚心| 伊人色综合久久天天| 国产1区2区3区精品美女| 精品一区在线播放| 欧美久久婷婷综合色| 亚洲蜜桃精久久久久久久| 国产精品主播直播| 欧美在线视频一区二区三区| 51午夜精品国产| 亚洲精品欧美在线| 成人免费毛片app| 亚洲高清视频一区| 久久久久国产精品麻豆| 欧美三级电影在线看| 中文字幕一区二区三区四区 | 国产嫩草影院久久久久| 免费一级欧美片在线观看| 国产精品麻豆免费版| 色偷偷久久一区二区三区| 欧美日韩成人一区| 欧美在线看片a免费观看| 色婷婷综合激情| 欧洲精品一区二区| 欧美精品日韩一本| 91精品国产91久久久久久一区二区 | 日韩二区三区四区| 免费美女久久99| 国产精品一区二区三区网站| 国产成a人亚洲精品| 欧美性bbwbbwbbwhd| 亚洲高清在线观看一区| 欧美在线观看你懂的| 精品少妇一区二区三区| 亚洲免费大片在线观看| 亚洲人成影院在线观看| 国产日本欧美一区二区| 国产日产精品一区| 亚洲午夜久久久| 精品一区二区在线观看| 99国产欧美久久久精品| 秋霞久久久久久一区二区| 日本福利一区二区| 久久免费国产精品| 亚洲一区二区三区三| 国产一二精品视频| 欧美日韩在线电影| 久久青草欧美一区二区三区| 黑人精品欧美一区二区蜜桃| 国产精品日韩高清| 91国产成人在线| 久久先锋资源网| 亚洲成人先锋电影| 国产91丝袜在线18| 色琪琪一区二区三区亚洲区| 成人av手机在线观看| 不卡av在线免费观看| 欧美日本精品一区二区三区| 天天综合网 天天综合色| 国产一区国产精品| 久久久久久久久久电影| 粉嫩蜜臀av国产精品网站| 欧美日韩一区小说| 日韩电影免费在线看| 日韩精品资源| 亚洲精品日韩一| 精品国产一区二区三区四区vr | 免费试看一区| 精品1区2区在线观看| 国产99久久久国产精品免费看| 在线观看不卡一区| 日韩激情视频网站| 亚洲欧美国产精品桃花| 一区二区三区日韩欧美精品| 久久婷婷人人澡人人喊人人爽| 中文天堂在线一区| www 成人av com| 久久久久久久久蜜桃| 91啪亚洲精品| 精品国产人成亚洲区| 不卡的av网站| 精品国产一区二区三区av性色 | 99久久99久久精品国产片果冻| 日韩欧美一卡二卡| 成人一区二区三区视频在线观看| 717成人午夜免费福利电影| 国产一区视频网站| 91麻豆精品国产91久久久更新时间| 玖玖九九国产精品| 欧美性猛交xxxx乱大交退制版| 美女一区二区视频| 欧美视频在线观看一区| 国产一区二区免费视频| 91精品国产丝袜白色高跟鞋| 国产成人丝袜美腿| 精品久久久久香蕉网| va亚洲va日韩不卡在线观看| 久久综合九色欧美综合狠狠| 91论坛在线播放| 国产三级欧美三级日产三级99| 成人av免费在线看| 亚洲欧洲性图库| 美媛馆国产精品一区二区| 一区二区三区加勒比av| 亚洲精品一卡二卡三卡四卡| 日韩1区2区3区| 欧美色综合影院| 国产精品一级在线| 26uuu精品一区二区| 不卡视频一区二区| 亚洲婷婷综合久久一本伊一区 | 亚洲人久久久| 美腿丝袜在线亚洲一区| 777奇米四色成人影色区| 不卡av免费在线观看| 国产三级欧美三级日产三级99| 精品蜜桃一区二区三区| 亚洲一区自拍偷拍| 91极品视觉盛宴| 国产成人综合在线观看| 国产亚洲综合在线| 免费在线成人av| 日韩电影免费在线| 欧美一区二区三区在线观看 | 日韩欧美国产高清| 国产精品三区四区| 亚洲综合无码一区二区| 欧美伊人久久大香线蕉综合69| 福利电影一区二区| 中文字幕av一区二区三区高 | 中文字幕不卡一区| 亚洲激情一区二区| 国产一区在线观看麻豆| 国产亚洲成年网址在线观看| 欧美极品jizzhd欧美| 免费视频最近日韩| 欧美v日韩v国产v| 好吊色欧美一区二区三区 | 久久久久se| 蜜臀av性久久久久av蜜臀妖精| 日韩欧美国产电影| 精品麻豆av| 久久精品72免费观看| 久久这里只精品最新地址| 久久综合色一本| 老鸭窝一区二区久久精品| 2023国产精品| 日韩精品福利视频| 国产麻豆精品在线观看| 亚洲国产精品v| 在线观看国产一区| www.日韩大片| 一区二区三区加勒比av| 欧美顶级少妇做爰| 国产原创精品| 美国十次综合导航| 国产女同互慰高潮91漫画| 尤物国产精品| 91丨九色丨黑人外教| 午夜婷婷国产麻豆精品| 欧美va亚洲va香蕉在线| 日韩电影免费观看在| 国产**成人网毛片九色| 亚洲男人的天堂在线观看| 欧美美女bb生活片| 蜜桃av噜噜一区二区三| 国产一区二区成人久久免费影院| 国产精品国产精品国产专区不片| 在线看日本不卡| 鬼打鬼之黄金道士1992林正英| 欧美a一区二区| 国产精品无圣光一区二区| 欧美午夜不卡在线观看免费| 国产91精品入口17c|