2013-02-28 119 views
14

考慮執行以下功能,JavaScript函數是否是異步的?

function loadPage() 
{ 
    takeInput(); 
    processInput(); 
    outputInput(); 
} 

在什麼樣的順序,他們會被執行(我有read它遵循棧所以選項2將是答案)?

選項#1

  1. takeInput();
  2. processInput();
  3. outputInput();

選項#2

  1. outputInput();
  2. processInput();
  3. takeInput();

回答

16

JavaScript函數是而不是異步。一些非常有限的功能集具有異步API:

addEventListener,setTimeout,setInterval。這是唯一的3個(我認爲這是非常令人驚訝的)。

它們允許您傳遞一個回調,可能會最終調用。例如計時器到期時,或者當用戶點擊某物時,或者AJAX請求完成時。

JavaScript有一個事件循環。事件循環會處理每個事件進來。如果您單擊按鈕3次,然後計時器到期,也將處理事件的順序。這一切都非常明確和確定。

此外,JavaScript沒有線程,它完全運行一個事件,直到在開始下一個事件之前沒有任何事情可以做(返回)。所以事件絕不會以任何方式干涉。這使您可以對數據狀態做出非常有力的假設。

+4

唯一的3?那麼,所有其他的呢? – Pointy 2013-02-28 16:54:39

+1

還有哪些?沒有其他的。分配一個onclick或onreadystatechange (例如)只是'addEventListener'的一個混蛋。 – Halcyon 2013-02-28 16:56:07

+2

XHR呢?那麼Node.js中所有可用的API呢? – Pointy 2013-02-28 16:58:03

0

不,默認情況下不是/作爲標準,雖然有異步方法。而且jQuery更使用異步行爲。但在每種情況下,這是主觀的,不能說「所有的JavaScript是這個」。

方法總是以它們被調用的順序執行;它們的異步性意味着任何可能在另一個之前完成,即使之後被調用。

8

JavaScript函數是異步的嗎?

有些是,大部分都沒有。

在什麼樣的順序,他們會被執行

他們將在調用它們的順序執行。由於它們都是從同一個函數中調用的,所以會以簡單的線性順序。

如果它們中的任何一個是以異步方式編寫的,那麼它們可能不會以相同的順序完成其所有活動。對於example

function a() { 
    console.log('a'); 
} 
function b() { 
    console.log('b'); 
} 
function c() { 
    console.log('c'); 
} 
function aAsync() { 
    setTimeout(a, 500); 
} 

function load() { 
    aAsync(); 
    b(); 
    c(); 
} 
load(); 
+1

所以C()會一直等待B()來使用,只要在B中所有的代碼是同步完成?所以b可以包含1000行syncronous代碼&c仍然會在b之後執行而不是?就是這個突出的操作順序時的代碼是父函數中異步確保^^ – Vincent 2015-01-15 10:36:30

+0

很好的例子。如果我們開始在b,c中添加異步代碼,將會成爲一個屠宰場。到那個,我們應該使用承諾:!d – 2016-03-07 13:35:15

1

JavaScript並不是一般異步的,但它確實有異步和事件驅動的方法。

Ajax調用是很大的異步方法。

對於事件,我不確定是否可以保證執行的順序,但我可能是錯誤的。

0

Javascript是一個單線程的野獸,所以嚴格來說,任務並不是異步的,就像產生子線程來執行代碼一樣。提供這種機制的機制造成了異步性的錯覺,但它仍然是單線程的。

+1

異步並行= – Quentin 2013-02-28 17:00:15

1

Javascript不是異步
它同步工作,即一次運行一行代碼。 運行javascript代碼時,首先創建一個全局執行上下文,如果您從全局執行上下文中調用函數,則另一個執行上下文由javascript引擎創建,並放置在執行堆棧的頂部(全局執行上下文已經在堆棧中),並且如果從該函數內部調用另一個函數,則會創建另一個執行上下文並且堆棧大小會不斷增加。

所以,JavaScript引擎保持在一個時間,在這個過程中運行此一行代碼,如果有任何事件/ HTTP請求火災,瀏覽器把它們放入事件隊列。所以,重點是JavaScript引擎不會處理隊列中的事件,直到執行堆棧爲空。 當引擎執行堆棧時,它會定期查看是否有任何隊列中的當前事件的事件處理程序,並類似地爲該處理程序創建執行上下文並運行其中的代碼。 因此,整個過程僅僅是同步的,而異步只是由瀏覽器的其他部分(如渲染引擎或http引擎)處理,而JavaScript引擎繼續同步運行代碼。

所以,你的情況, 從哪個方面功能loadpage被調用,它的執行上下文被創建並與放置在堆棧的頂部。然後,它調用輸入輸入函數,它的exec。上下文被創建,並且其他函數上下文將不會被創建並被放置在堆棧中,直到takeinput上下文從執行堆棧彈出。 因此,正確的順序將是takeinput,processinput和outputinput。

我希望它能回答你的問題。