简体   繁体   English

在返回值方面,异步 function 中的 await 关键字有什么意义?

[英]What is the point of the await keyword within an async function in terms of returning a value?

I've researched many many posts and articles, and documentation.我研究了许多帖子和文章以及文档。 I'm seeking deeper understanding.我正在寻求更深入的理解。

From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await来自https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await

The await expression causes async function execution to pause until a Promise is settled, [...] await表达式导致async function 执行暂停,直到Promise被解决,[...]

 let fetchLocation = () => { //fetches information from satellite system and //returns a Vector2 of lat long on earth return new Promise(resolve => { setTimeout(() => { resolve({ lat: 73, long: -24 }); }, 2000); }); } //async functions automatically return a promise. let main = async() => { //awaits the promises resolution let result = await fetchLocation(); console.log("I'm the awaited promise result", result) //immediately returns a promise as promise pending return result; } console.log(main().then(res => console.log("I'm the original promise, just passed along by the async function, it didn 't a-wait for me", res)))

Before going down this rabbit hole, I knew async/await was syntactical sugar to make async code look synchronous.在进入这个兔子洞之前,我知道 async/await 是让异步代码看起来同步的语法糖。

I therefore fully expected to see main return the lat long coordinates.因此,我完全期望看到 main 返回 lat long 坐标。 Instead it returns a promise.相反,它返回 promise。

A couple questions.几个问题。

  1. Is the MDN documentation wrong? MDN 文档有错吗? Does it not actually pause execution?它实际上不会暂停执行吗? It seems that the await keyword does not actually "pause" function execution... invoking main immediately returns a Promise<pending> object.似乎 await 关键字实际上并没有“暂停” function 执行...调用 main 立即返回一个Promise<pending> object。 However, after it returns we receive the value of the fulfilled promise in the awaited variable result .然而,在它返回后,我们在等待的变量result中收到了已完成的 promise 的值。 I suppose this came from the event loop?我想这来自事件循环? (And an async return statement is still synchronous.) (并且异步返回语句仍然是同步的。)

  2. So it seems that await unwraps a promise, and async wraps a promise, but you need to use await within async.因此,await 似乎解开了 promise,而 async 则包装了 promise,但您需要在 async 中使用 await。 I get that await might actually be promise.then() underneath the hood but if they want to make it fully synchronous in appearance, why not have the async function return the resolved promise value when used with await?我知道 await 实际上可能是引擎盖下的 promise.then() 但如果他们想让它在外观上完全同步,为什么不让异步 function 返回解析的 promise 值与 await 一起使用? Otherwise async await seems a bit redundant.否则 async await 似乎有点多余。

Is the MDN documentation wrong? MDN 文档有错吗?

No

Does it not actually pause execution?它实际上不会暂停执行吗?

It pauses the execution of the async function, hands a Promise back to the calling function — because it hasn't reached the point in the async function where it knows what to return — then the execution of the calling function (and the rest of the code) continues. It pauses the execution of the async function, hands a Promise back to the calling function — because it hasn't reached the point in the async function where it knows what to return — then the execution of the calling function (and the rest of the代码)继续。

However, after it returns we receive the value of the fulfilled promise in the awaited variable result.但是,在它返回后,我们在等待的变量结果中收到了已完成的 promise 的值。 I suppose this came from the event loop?我想这来自事件循环?

When the event loop stops being busy (running the code that called the async function in the first place and anything else that it picks up in the meantime) and the promise that was being await ed resolves, then the async function is woken up and given the resolved value of the function to continue processing. When the event loop stops being busy (running the code that called the async function in the first place and anything else that it picks up in the meantime) and the promise that was being await ed resolves, then the async function is woken up and given function 的解析值继续处理。

why not have the async function return the resolved promise value when used with await?为什么不让异步 function 在与等待一起使用时返回已解析的 promise 值?

Because that would block the entire event loop, which is why asynchronous logic (starting with callback style APIs) was introduced into JS in the first place.因为这会阻塞整个事件循环,这就是为什么首先将异步逻辑(从回调样式 API 开始)引入 JS 的原因。

Otherwise async await seems a bit redundant.否则 async await 似乎有点多余。

Consider a situation where you want to request a number of URLs from an API serially (so that you don't shove too many simultaneous requests at the API):考虑一种情况,您希望从 API 串行请求多个 URL(这样您就不会在 API 上同时发送太多请求):

const data = [];
for (let i = 0; i < urls.length; i++) {
    const response = await fetch(urls[i]);
    const response_data = await response.json();
    data.push(response_data);
}

If you were to rewrite that without await then you'd probably end up with something recursive to count your way through the loop.如果您要在不await的情况下重写它,那么您最终可能会得到一些递归来计算您通过循环的方式。 It would be significantly more complex.它会复杂得多。

async / await makes dealing with complex combinations of promises simple, and simple promises trivial. async / await使得处理复杂的 Promise 组合变得简单,而简单的 Promise 变得微不足道。

knew async/await was syntactical sugar to make async code look synchronous.知道 async/await 是使异步代码看起来同步的语法糖。

And it does that inside the async function and only inside it.async function内部并且在其中执行此操作。

It doesn't really pause the function, it just allows you to write the rest of the function code as if it were.它并没有真正暂停 function,它只是允许您像这样编写 function 代码的 rest。 But it's really just wrapping the rest of the code of the function into a .then() .但这实际上只是将 function 的代码的 rest 包装到 .then .then()中。

Eg例如

await foo = someFunc();
console.log(foo);

is executed like像这样执行

someFunc().then((foo => {
    console.log(foo);
});

Since it's really still asynchronous, you can't return the resolved value, because the original calling function returns immediately.由于它确实仍然是异步的,因此无法返回解析后的值,因为原来的调用 function 立即返回。 But if the calling function is also declared async , it returns a Promise , and the caller can either use await again (so it appears to be synchronous) or use .then() .但是如果调用 function 也被声明为async ,它会返回一个Promise ,调用者可以再次使用await (所以它看起来是同步的)或使用.then()

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

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