2013-05-13 123 views
17

我想抓住Javascript異步函數和回調。默認爲Javascript同步(阻止)或異步(非阻塞)

我陷入了回調函數的概念,在某些地方我正在閱讀它們:它們用於順序執行代碼(主要在jquery的上下文中,例如動畫)和一些特別在Nodejs上下文中的地方;它們用於並行執行異步並避免代碼的阻塞。

因此,在這個主題的一些專家請澄清這一點,並清除我腦海中的這個模糊(例子??)。 所以我可以讓我的腦海回調函數的用法

或者說是完全取決於你在哪裏調用/放置一個回調函數在代碼的地方嗎? 。

感謝,

PS:我很害怕,這個問題將是接近主觀的,但我依然可以期待這個具體的答案(也許是一些例子)

編輯:其實這是例如,從互聯網這讓我ambigous:

function do_a(){ 
    // simulate a time consuming function 
    setTimeout(function(){ 
    console.log('`do_a`: this takes longer than `do_b`'); 
    }, 1000); 
} 

function do_b(){ 
    console.log('`do_b`: this is supposed to come out after `do_a` but it comes out before `do_a`'); 
} 

do_a(); 
do_b(); 

結果

`do_b`: this is supposed to come out after `do_a` but it comes out before `do_a` 
`do_a`: this takes longer than `do_b` 

當JS是順序的,那麼根據我的理解,do_b應該總是在do_a之後出現。

+6

JavaScript是JavaScript的;它取決於上下文,用法,引擎等。 – 2013-05-13 14:00:00

+0

你能否提供一些你不確定它是否阻塞與非阻塞的示例代碼? – Matt 2013-05-13 14:06:11

+0

JavaScript通常是同步的,但根據定義,setTimeout是異步的。這裏有一個很好的入門知識:https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout – 2013-05-13 14:25:02

回答

2

在節點長時間運行的進程中,使用process.nextTick()排隊函數/回調。這通常是在節點的API中完成的,除非你的編程(在api之外)有阻塞的東西或長時間運行的代碼,那麼它對你沒有太大的影響。下面的鏈接應該更好地解釋它,然後我可以。

howtonode process.nextTick()

jQuery的AJAX也需要回調和諸如它的編碼不就移動到下一個代碼塊之前等待服務器的響應。它只是記住在服務器響應時運行的功能。這基於瀏覽器公開的XMLHTTPRequest對象。 XHR對象會記住在響應返回時要回調的函數。

setTimeout(fn, 0) javascript會在調用堆棧爲空時運行一個函數(下一個可用的空閒tick),它可以用來創建類似異步的特性。 setTimeout(fn, 0) question on stackoverflow

爲了總結javascript的異步能力與他們在javascript中編程的環境同樣重要。除非您使用一些API /腳本,否則您不會通過使用大量函數調用和回調來獲得任何魔力。

Jquery Deferred Object是jQuery的異步功能的另一個好鏈接。 Google搜索可能會找到關於jQuery Deferred如何工作的信息以獲取更多信息。

22

JavaScript的核心很大程度上是同步的,因爲在完成之前,函數完全完成了他們的任務。在AJAX出現之前,實際上只有setTimeout和setInterval提供了異步行爲。

但是,很容易忘記事件處理程序是有效的異步代碼。附加一個處理程序不會調用處理程序代碼,並且該代碼將在未來某些不可知的時間之前執行。

然後來到了AJAX,它調用了服務器。這些調用可以配置爲同步,但開發人員通常更喜歡異步調用並使用回調方法來實現它們。

然後,我們看到了JS庫和工具包的激增。這些努力均勻化不同瀏覽器的事物實現,並建立在異步代碼的回調方法上。你也開始看到像數組迭代或CSS查詢結果處理這樣的更多同步回調。

現在,我們看到了組合中的延遲和承諾。這些對象表示長時間運行的操作的值,並提供用於處理該值的API。

NodeJS傾向於一種異步的方法來處理許多事情;這是事實。然而,這更像是一個設計決定,而不是JS的任何固有的異步性質。

10

JavaScript始終是一種同步(阻塞)單線程語言,但我們可以通過編程使JavaScript異步。

同步代碼:

console.log('a'); 
console.log('b'); 

異步代碼:

console.log('a'); 
setTimeout(function() { 
    console.log('b'); 
}, 1000); 
setTimeout(function() { 
    console.log('c'); 
}, 1000); 
setTimeout(function() { 
    console.log('d'); 
}, 1000); 
console.log('e'); 

此輸出:A E B C d

+0

在這種情況下阻塞是什麼意思? – 2016-03-14 18:38:09