關於 js 中的回調函數 callback

本文寫於1年前 曾經的學習文章現在拿出來分享

前言程序員

其實我一直很困惑關於js中的callback,困惑的緣由是,學習中這塊看的資料少,可是平時又常常見,偶爾複製一下前人代碼,功能實現了也就再也不去追其起因,這麼着,這個callback的概念就愈來愈混亂,由於你總感受它是你Ajax請求後調用的那個函數,又感受它是你某一個函數中的形參而已,而當你有一天看到一點關於Node.js的代碼後你會更加崩潰,由於你會發現不少的callback,可是這麼着下去確定是不行的,由於不少的東西若是隻是知道概念和理論,沒有實踐出結果,沒有思考和感覺,這些東西永遠不是你的,因此任何關於技術上用到的東西都應該去花時間鑽研一下,學習 付出時間 實踐都會搞明白的,還會沉澱不少思想,因此最近一直在瀏覽相關的文章和資料,本身在項目中也用到了一些去實踐,這樣一輪下來後,你會發現明亮了不少設計模式

一 .搞清楚異步和同步

異步async/同步sync數組

舉個小栗子瀏覽器

1.早上起來不論你是先刷牙仍是先洗臉,都要等一個事情完畢後才能進行下一項,這就是一個同步的例子多線程

2.而後刷牙的時候你也能夠燒水喝 (不用等你刷完牙)這就是一個異步的例子異步

來段異步代碼示例async

js裏面最基礎的異步實現

運行結果

以上代碼會先執行函數a,並且不會等到a中的延遲函數執行完才執行函數b, 在延遲函數被觸發的過程當中就執行了函數b,當js引擎的event 隊列空閒時纔會去執行隊列裏等待的setTimeout的回調函數,這就是一個異步的例子

題外話

調用 setTimeout 函數會在一個時間段過去後在隊列中添加一個消息。這個時間段做爲函數的第二個參數被傳入。若是隊列中沒有其它消息,消息會被立刻處理。可是,若是有其它消息,setTimeout 消息必須等待其它消息處理完。所以第二個參數僅僅表示最少的時間 而非確切的時間

因此即便,時間設置爲0,也是會照樣先執行函數b

來段同步代碼示例


運行結果爲1

print函數會等change函數完成以後去執行,因此結構輸出爲1,由於change函數修改了全局變量a的值,change執行以後才執行的print函數

二.回調函數究竟是什麼

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

以上解釋是Google得出的解釋,很是清晰簡明,有時候我以爲英文理解要比翻譯成中文二次理解更清楚

來看幾個經典的回調函數代碼,我敢保證你必定用過他們

異步請求的回調函數

點擊事件的回調函數

數組中遍歷每一項調用的回調函數

同步回調的例子

因此回調與同步、異步並無直接的聯繫,回調只是一種實現方式,既能夠有同步回調,也能夠有異步回調,還能夠有事件處理回調和延遲函數回調,這些在咱們工做中有不少的使用場景

因此其實並非咱們不認識回調函數,而是咱們都縈繞在了這個「callback「 這個詞上,當你在一個函數中看到它是就會困惑,其實它只是一個形參名字而已函數

三.爲何寫回調函數學習

看了以上的簡單介紹以後,是否是對callback再也不陌生和以爲神祕,因此盡情的去使用吧,線程

1.關於回調函數和js單線程以及js異步機制

咱們都知道js是單線程的,這種設計模式給咱們帶來了不少的方便之處,咱們不須要考慮各個線程之間的通訊,也不須要寫不少燒腦的代碼,也就是說js的引擎只能一件一件事的去完成和執行相關的操做,因此全部須要執行的事情都像排隊同樣,等待着被觸發和執行,但是若是這樣的話,若是在隊列中有一件事情須要花費不少的時間,那麼後面的任務都將處於一種等待狀態,有時甚至會出現瀏覽器假死現象,例如其中有一件正在執行的一個任務是一個死循環,那麼會致使後續其餘的任務沒法正常執行,因此js在同步機制的缺陷下設計出了異步模式

在異步執行的模式下,每個異步的任務都有其本身一個或着多個回調函數,這樣當前在執行的異步任務執行完以後,不會立刻執行事件隊列中的下一項任務,而是執行它的回調函數,而下一項任務也不會等當前這個回調函數執行完,由於它也不能肯定當前的回調合適執行完畢,只要引它被觸發就會執行,舉個例子

圖片資源還未請求完畢

上圖能夠看到,我要購買一個東西,當我點進物品的詳情頁以後,圖片資源還未請求完畢,而此時我就能夠點擊add to cart, 發起另外一個請求,js任務列表中的添加購物車事件就會開始執行,它的執行也不會干擾到圖片資源的請求任務,這也是異步執行機制的妙處

2.js的單線程瀏覽器內核的多線程

說到js的單線程,順便再瞭解一下關於瀏覽器內核的多線程,關於瀏覽器工做原理此處不作講解,由於本身研究的不深刻,等待研究學習研究透徹再分享

瀏覽器常駐三大線程: js引擎線程,GUI渲染線程,瀏覽器事件觸發線程

看到此圖你是否是會豁然開朗許多,由於瀏覽器是一個多線程的執行環境,在瀏覽器的內核中分配了多個線程,最主要的線程之一便是js引擎的線程,同時js事件隊列中的異步請求,交互事件觸發,定時器等事件都是由瀏覽器的事件觸發線程進行監聽的,瀏覽器的事件觸發線程被觸發後會把任務加入到js 引擎的任務隊列中,當js 引擎空閒時候就會開始執行該任務

完結

以上就是本篇文章的所有內容,由對回調函數的陌生到熟悉和使用,以及對同步/異步的概念,還有js的執行機制以及瀏覽器內核的多線程機制相信你們都有了一個簡單的知識脈絡,但願經過此文提到的內容,每一個小夥伴去查閱更深刻的資料,於此同時我也會不斷的去修繕,因此咱們不能作一個知其然而不知其因此然的程序員,要有充分的好奇心去學習它,帶着學習讓咱們受益的心態去作和研究本身感興趣的東西是一件很是快樂的事情,但願我能夠把個人快樂帶給每一位看文章的小夥伴,也但願你多多給我提出意見,讓咱們一塊兒在學習的路上共同發現和成長,2107年歡迎你和我一塊兒作一個不斷努力學習的知識分子

Cayley 一個不斷努力學習的女程序員

相關文章
相關標籤/搜索