2016-08-16 53 views
0

我創建了一個小腳本來更好地理解回調。瞭解回調

從下面的腳本中,我預期的行爲是:「http.get運行並且平均需要200 ms,for循環」i「的增量平均需要2500 ms,在200 ms時,進程應該退出,腳本應該已經停止工作。爲什麼打印所有我嗎?如果我明白這更好,我想我明白回調。

var http = require("http"); 
var starttime = new Date(); 

//Function with Callback 
for (var j =0; j<10; j++){ 
    http.get({host : 'nba.com'}, function(res){ 
     console.log("Time Taken = ", new Date() - starttime, 'ms'); 

     process.exit(); 
    }).on('error', function(er){ 
     console.log('Got Error :', er.message); 
    }) 
} 

//Loop that exceeds callback trigger time 
for(var i=1; i<10000; i++){ 
    console.log(i); 
} 

console.log("Time Taken = ", new Date() - starttime, 'ms'); 
+0

for循環是同步的,其中的代碼是異步的。它通過for循環啓動get async get調用。 for循環在回調被觸發前退出。互聯網上有很多文檔和示例來說明異步是如何工作的。 – bryanmac

+0

謝謝bryanmac。我會檢查出來。它現在清晰如雲。 – PatrickJames

回答

3

的Javascript中的node.js是單線程和I/O的事件驅動使用一個事件隊列,因此你的異步回調信號完成了http請求,直到你原來的Javascript線程完成並返回控制權返回系統,然後可以從事件隊列中提取下一個事件服務完成t他http請求。

因此,您的for循環將在任何http響應可以被處理之前運行完成。

這裏是循序漸進的過程:

  1. 你的第一個for循環運行,併發送10個HTTP請求。
  2. 這些http請求使用異步網絡在後臺運行。當其中一個完成並有響應時,http模塊會將一個事件放入Javascript事件隊列中,並且當JS解釋器完成其他活動時將它從事件隊列中拉出。
  3. 您的第二個for循環運行完成,所有i值都輸出到控制檯。
  4. 腳本結束。
  5. JS解釋器然後檢查事件隊列以查看是否有任何未決事件。在這種情況下,會有一些http響應事件。 JS解釋器從事件隊列中提取最舊的事件並調用與之相關的回調。
  6. 回調完成後,將從事件隊列中提取下一個事件,並繼續該過程,直至事件隊列爲空。
  7. 如果您的任何回調呼叫process.exit(),則會短路剩餘的回叫並立即退出處理。

雖然這對方的回答是爲瀏覽器寫的,事件驅動,單線程概念是相同的,因爲它是在node.js中所以這對方的回答可以解釋一些東西給你:How does JavaScript handle AJAX responses in the background?

+0

謝謝Jfiend00。這清楚地解釋了它。 由於單線程,CPU同步時,我忘記網絡或I/O的事情是異步的。 For循環與CPU相關,無I/O。說得通。 – PatrickJames