2017-08-09 120 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例子 –