简体   繁体   English

JavaScript 中没有等待的异步函数

[英]Async function without await in JavaScript

I have two functions, a and b , that are asynchronous, the former without await and the latter with await .我有两个函数, ab ,它们是异步的,前者没有await ,后者有await They both log something to the console and return undefined .他们都将某些内容记录到控制台并返回undefined After calling either of the function, I log another message and look if the message is written before or after executing the body of the function.在调用任一函数后,我记录另一条消息并查看该消息是在执行函数主体之前还是之后编写的。

 function someMath() { for (let i = 0; i < 9000000; 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() { console.log('clicked on a button') a() console.log('after a (no await) call') } bButton.onclick = function() { console.log('clicked on b button') b() console.log('after b (await) call') }
 <button id="aButton">test without await (a)</button> <button id="bButton">test with await (b)</button> <button id="clear">clear console</button>

If you launch test without await , the function seems to work as if it was synchronous.如果您在没有await的情况下启动测试,该功能似乎就像是同步的一样工作。 But with await , the messages are inverted as the function is executed asynchronously.但是对于await ,消息会随着函数的异步执行而反转

How does JavaScript execute async functions when no await keyword is present?当没有await关键字时,JavaScript 如何执行async函数?


Real use case: I have an await keyword which is conditionally executed, and I need to know if the function is executed synchronously or not in order to render my element:真实用例:我有一个有条件执行的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: The title has the JavaScript keyword to avoid confusion with the same questions in other languages (ie Using async without await ) PS:标题有 JavaScript 关键字以避免与其他语言中的相同问题混淆(即使用 async without await

Mozilla documentation : Mozilla 文档

An async function can contain an await expression, that pauses the execution of the async function and waits for the passed Promise's resolution, and then resumes the async function's execution and returns the resolved value.异步函数可以包含一个等待表达式,它暂停异步函数的执行并等待传递的 Promise 的解析,然后恢复异步函数的执行并返回解析的值。

As you assumed, if no await is present, the execution is not paused and your code will then be executed synchronously as normal.正如您所假设的,如果不存在等待,则不会暂停执行,然后您的代码将照常同步执行。

Everything is synchronous until a Javascript asynchronous function is executed.在执行 Javascript 异步函数之前,一切都是同步的。 In using async-await await is asynchronous and everything after await is placed in event queue.在使用 async-await 时, await是异步的,await 之后的所有内容都放在事件队列中。 Similar to .then() .类似于.then()

To better explain take this example:为了更好地解释,举个例子:

function main() {
  return new Promise( resolve => {
    console.log(3);
    resolve(4);
    console.log(5);
  });
}

async function f(){
    console.log(2);
    let r = await main();
    console.log(r);
}

console.log(1);
f();
console.log(6);

As await is asynchronous and rest all is synchronous including promise thus output is因为await是异步的,而其余的都是同步的,包括 promise,因此输出是

1
2
3
5
6
// Async happened, await for main()
4

Similar behavior for main() without promise too: main()的类似行为也没有承诺:

function main() {
    console.log(3);
    return 4;
}

async function f(){
    console.log(2);
    let r = await main();
    console.log(r);
}

console.log(1);
f();
console.log(5);

Output:输出:

1
2
3
5
// Asynchronous happened, await for main()
4

Just removing await will make whole async function synchronous which it is.只需删除await将使整个async函数同步。

function main() {
    console.log(3);
    return 4;
}

async function f(){
    console.log(2);
    let r = main();
    console.log(r);
}

console.log(1);
f();
console.log(5);

Output:输出:

1
2
3
4
5

The function is executed the same with or without await .无论有无await ,该函数的执行方式都相同。 What await does is automatically wait for the promise that's returned by the function to be resolved. await所做的是自动等待函数返回的 promise 被解析。

await timeout(1000);
more code here;

is roughly equivalent to:大致相当于:

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

The async function declaration simply makes the function automatically return a promise that's resolved when the function returns. async function声明只是使函数自动返回一个在函数返回时解决的承诺。

As other answers say/indicate: an async function just runs on spot until it encounters an await - if there is no await , it runs completely.正如其他答案所说/表明的那样: async function只是在现场运行,直到遇到await - 如果没有await ,它会完全运行。

What may be worth adding that async unconditionally makes your result a Promise .可能值得添加的是async无条件地使您的结果成为Promise So if you return something, there is a difference already and you simply can not get the result without returning to the JS engine first (similarly to event handling):所以如果你返回一些东西,已经有区别了,如果不首先返回 JS 引擎,你根本无法得到结果(类似于事件处理):

 async function four(){ console.log(" I am four"); return 4; } console.log(1); let result=four(); console.log(2,"It is not four:",result,"Is it a promise ?", result instanceof Promise); result.then(function(x){console.log(x,"(from then)");}); console.log(3);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM