2017-08-09 22 views
4

我有兩個函數ab是異步的,前者沒有await,後者是await。他們都將某些內容記錄到控制檯並返回undefined。在調用函數的任何一個之後,我會記錄另一條消息,並查看消息是在執行函數主體之前還是之後寫入的。不用等待在Javascript中的異步函數

function someMath() { 
 
    for (let i = 0; i < 3000000; i++) { Math.sqrt(i**5) } 
 
} 
 

 
function timeout(n) { 
 
    return new Promise(cb => setTimeout(cb, n)) 
 
} 
 

 
// ------------------------------------------------- a (no await) 
 
async function a() { 
 
    someMath() 
 
    console.log('in a (no await)') 
 
} 
 

 
// ---------------------------------------------------- b (await) 
 
async function b() { 
 
    await timeout(100) 
 
    console.log('in b (await)') 
 
} 
 

 
clear.onclick = console.clear 
 

 
aButton.onclick = function() { 
 
    a() 
 
    console.log('after a (no await) call') 
 
} 
 

 
bButton.onclick = function() { 
 
    b() 
 
    console.log('after b (await) call') 
 
}
<button id="aButton">test without await</button> 
 
<button id="bButton">test with await</button> 
 
<button id="clear">clear console</button>

如果啓動測試,而不await功能似乎工作,如果它是同步的。但與await,該消息是反轉作爲功能異步執行。

所以我的問題是:JavaScript如何執行async功能當沒有await關鍵字存在?


實際使用情況:我有的conditionnaly執行的await關鍵字,我需要知道,如果是同步或不按順序執行的功能,以使我的元素:

async function initializeComponent(stuff) { 
    if (stuff === undefined) 
     stuff = await getStuff() 
    // initialize 

    if (/* context has been blocked */) 
     renderComponent() // render again if stuff had to be loaded 
} 

initializeComponent() 
renderComponent() 

PS:標題有javascript關鍵字,以避免與其他語言的相同問題混淆(即https://stackoverflow.com/q/12016567/6320039)

+0

您還需要將'bButton.onclick'函數轉換爲異步函數並等待'b()'結束才能獲得所需的日誌。 –

+0

@JoseHermosillaRodrigo我不想等待所需的日誌,我想知道使用或不使用'await'關鍵字改變同步功能。如果沒有,也許爲什麼我的測試是錯誤的。我會在最後更新我的真實使用案例,也許它會更清晰。 –

回答

4

從Mozilla的文檔

異步函數可以含有AWAIT表達,即暫停 執行異步函數的,並等待通過Promise的 分辨率,然後重新開始異步函數的執行和 返回解決的值。

如您所示,如果沒有await存在,執行不會暫停,您的代碼將被同步執行。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

+0

是否有冗餘'async'關鍵字的eslint規則?我不認爲同步函數應該有它 – Blauhirn

+0

也許這一個:https://eslint.org/docs/rules/require-await – Karim

+0

哦,是的,那是一個。錯過它莫名其妙:D謝謝 – Blauhirn

1

該功能是執行相同或不執行awaitawait所做的是自動等待函數返回的promise被解析。

await timeout(1000); 
more code here; 

大致等同於:

timeout(1000).then(function() { 
    more code here; 
}); 

async function聲明只是使功能自動返回的問題得以解決函數返回時的承諾。

-1

警告:如果你定義一個異步功能時無法將其轉換爲同步功能簡單地調用它沒有「等待」,如果你不使用的await,調用下面的代碼將被執行平行。 我已經意識到了這個問題,當我使用了很多嵌套的異步函數,在等待或不在裏面。

例子:我們有3個異步功能:

async function aFather 

async function aChild 

(syncn) function Child 

async function aGrandChild 

裏面aFather,我們可以稱之爲aChild或兒童;

在aChild裏面,我們可以調用aGrandChild;

aFather 
    await aChild - The code will stop here - and inside if find aGrandChild 
    (...below code...) 

aFather 
    aChild - The code will not stop, but will stop inside with 'await aGrandChild' 
    (...below code...) 
    * This can produce errors because your below code need values produced in aChild 
    * so if you call an async function without await, take care about that.  

aGrandChild 
    Child - The code will stop here 
    (...below code...) 
+0

我不明白你想說什麼......也許你可以編輯你的代碼,使其真正的JavaScript例子 –