翻譯練習javascript
原博客地址:JavaScript: What the heck is a Callback?java
在6分鐘內經過簡單的例子學習和理解回調的基本原理。服務器
簡單地說:回調就是一個在另外一個函數執行完成後再去執行的函數--所以得名回調。app
複雜點講:在JavaScript中,函數是對象。所以,函數能夠把其餘函數當作參數,也能夠被其餘函數返回。這樣作的函數稱爲高階函數。任何被當作參數傳遞的函數都叫回調函數。函數
上面已經講了不少,讓咱們經過一些例子把這些去細化一下。學習
有一條很是重要的緣由:JavaScript是一門事件驅動的語言。這意味着,JavaScript在監聽其餘事件的同時會繼續執行,而不是在繼續執行以前去等待響應。翻譯
function first(){ console.log(1); } function second(){ console.log(2); } first(); second();
正如你指望的那樣,函數first
會首先執行,函數second
會接着執行--控制檯打印以下:code
// 1 // 2
目前看來一切良好。對象
可是,若是函數first
包含一些不會當即執行的代碼會發生什麼呢?好比說,一個API請求,咱們必須去發送請求而後等待響應嗎?爲了模擬這種動做,咱們使用setTimeout
--在JavaScript
中,這個函數將會在設定的一段時間後去調用一個函數。咱們來把咱們的函數延遲500ms去模擬一個API請求。咱們的新代碼像下面這樣:教程
function first(){ // Simulate a code delay setTimeout( function(){ console.log(1); }, 500 ); } function second(){ console.log(2); } first(); second();
如今你理不理解setTimeout()
怎麼工做的並不重要。如今最重要的是,你看咱們把console.log(1);
移動到500ms的延時中。那麼,咱們如今執行代碼會發生什麼呢?
first(); second(); // 2 // 1
儘管咱們先調用first()
這個函數,可是咱們卻在second()
以後纔打印出來他的結果。
這並非JavaScript沒要按照咱們想的順序去執行咱們的函數,而是JavaScript在執行second()
函數以前並無等待first()
函數的響應。
因此,爲何要給你展現這些呢?由於你不能一個接一個的去調用函數,而後但願它們以正確的順序去執行。回調是一種可以保證某些代碼直到一些代碼執行完纔去觸發的方式。
好吧,說的夠多的了,讓咱們來建立一個回調。
首先,打開你的Chrome開發者控制檯(Windows: Ctrl + Shift + J)(Mac: Cmd + Option + J),而後在控制檯輸入下面的函數聲明:
function doHomework(subject) { alert(`Starting my ${subject} homework.`); }
在上面,咱們建立了一個叫作doHomework
的函數。咱們的參數接受一個參數--咱們正在學習的課程。經過在控制檯輸入如下代碼來調用你的函數:
doHomework('math'); // Alerts: Starting my math homework.
如今,讓咱們來添加回調--做爲doHomework()
函數的最後一個參數,咱們能夠傳入回調。隨後,在咱們調用doHomework()
時,回調函數被定義爲它的第二個參數。
function doHomework(subject, callback) { alert(`Starting my ${subject} homework.`); callback(); } doHomework('math', function() { alert('Finished my homework'); });
如你所見,若是你在控制檯輸入上面的代碼,你會連續收到兩次警告:先是「starting homework」,再是「finished homework」。
可是回調函數並非必須在咱們的函數調用中定義,它們能夠向下面這樣在其餘地方被定義:
function doHomework(subject, callback) { alert(`Starting my ${subject} homework.`); callback(); } function alertFinished(){ alert('Finished my homework'); } doHomework('math', alertFinished);
這個例子的結果和上一個的如出一轍,可是設置卻有一點區別。咱們在調用doHomework()
的時候,把函數定義alertFinished
做爲參數傳給了它。
上週我發佈了一篇文章,這篇文章中代碼運行的惟一緣由就是Twitters API。當你對一個API發起請求時,你必須等到它響應才能對相應進行操做。這是一個現實生活中關於回調的完美例子。下面是這個請求的代碼:
T.get('search/tweets', params, function(err, data, response) { if(!err){ // This is where the magic will happen } else { console.log(err); } })
T.get
僅僅表示咱們在向Twitter發起一個get請求。search/tweets
請求中有三個參數,分別是:請求的路由、查詢的參數param和咱們的回調--一個匿名函數。回調在這裏很重要,由於在運行到後面的代碼以前,咱們須要先從服務器獲取到響應。咱們不知道在咱們講參數經過get請求發送到search/tweets
後咱們的API請求成功與否,咱們只能等着。一旦Twitter作出響應,咱們的回調函數就會被調用。Twitter要麼返回一個錯誤信息給咱們,或者返回響應對象給咱們。在咱們的回調函數中,咱們能夠經過if()
語句去肯定咱們的請求是成功了仍是失敗了,而後相應地對新數據作出處理。
幹得不錯。理想狀況下,你如今已經理解了什麼是回調還有它是怎麼工做的。這僅僅是回調的冰山一角,還有不少你須要去學習。我每週會發布了一些文章/教程,若是你想被加入到個人once-weekly郵箱列表,在這裏了輸入你的郵箱吧。