真的很困惑从异步函数返回的承诺 [英] Really confused about promise being returned from async function

查看:49
本文介绍了真的很困惑从异步函数返回的承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我知道 async 函数在遇到 await 关键字时立即返回一个挂起的 promise,如果没有使用 await 关键字,async 函数返回的 promise 将被解析为我们从 async 函数返回的值,例如这个:

So I do know that async function returns a pending promise as soon as it hits the await keyword and if there's no await keyword used, the promise that async function returns will be resolved to the value that we return from our async function like this:

async function f() {
    let p = await (new Promise(r => {
        setTimeout(r, 2000, 100)
    }))
    return p;
}

let p = f();
console.log(p); // pending, because its awaiting.

第二个例子:

async function f() {
    let p = 'someValue';
    return p;
}
let p = f();
console.log(p); // {<fulfilled>: "someValue"}

第二个例子也很有意义,我们返回了 'someValue',正如 MDN 所说,它包含在 Promise.resolve('someValue') 中,这就是返回的内容.

2nd example also makes perfect sense, we're returning 'someValue' which as MDN says is wrapped in Promise.resolve('someValue') and that's what that's returned.

现在,这段代码打印的内容让我很困惑,它记录了一个未决的承诺!

Now, what this code prints confuses me so much, it logs a pending promise!

(我知道我没有在这里使用 await,这是故意的)

async function f() {
    let p = new Promise(r => r(113));
    return p;
}
let af = f();
console.log(af)

我们正在我们的 async f 函数中创建一个立即解决的承诺,这就是我在异步函数的默认创建承诺中返回的承诺,那么为什么该日志挂起?

We are creating a promise inside our async f function that's resolved immediately and that's the promise I return in my default created promise of async function so why does that log pending?

即使它未决,当我展开该对象时,我同时看到了这一点:

And even though its pending, when I expand that object, I see this at the same time:

[[PromiseResult]]: 113

有人可以帮忙吗?

推荐答案

这可能是因为 JavaScript 引擎需要扁平化"返回的承诺.

This probably happens because the JavaScript engine needs to "flatten" the returned promise.

console.log(Promise.resolve(113)); //=> fulfilled

const a = async () => 113;
console.log(a()); //=> fulfilled

const b = async () => Promise.resolve(113);
console.log(b()); //=> pending

最后一个场景记录了一个挂起的承诺.这可能是因为 JavaScript 引擎看到您从异步函数返回了一个承诺.在这种情况下,当您 await b() 时,您期望 113 作为结果.异步函数总是返回一个承诺.如果此承诺的解析值(异步函数的返回值)是另一个承诺,则该承诺被扁平化".

The last scenario logs a pending promise. This is probably because the JavaScript engine sees that you return a promise from an async function. In this scenario, when you await b(), you expect 113 as a result. An async function always returns a promise. If the resolved value (return value of an async function) of this promise is another promise then the promise is "flattened".

为了更好地说明这一点,将 b 的返回值想象为(Firefox 控制台符号):

To better demonstrate the point, imagine the return value of b as (Firefox console notation):

Promise { <state>: "pending", <value>: Promse { <state>: "fulfilled", <value>: 123 } }

而第一个代码块和a的返回值是:

Whereas the return value of both the first code block and a is:

Promse { <state>: "fulfilled", <value>: 123 }

嵌套 Promise 的扁平化由引擎完成,并且可能添加到事件循环的末尾,从而在当前运行上下文之后运行.这意味着外部承诺在发生之前待定.

The flattening of nested promises is done by the engine and probably added to end of the event loop and thus ran after the current running context. Which means that the outer promise is pending until that happens.

这种行为可能取决于引擎,所以我不会依赖这种行为.Promise 实例是对最终值的承诺,应如此对待.永远不要期望承诺会立即解决.如果您期望一个已履行的承诺,您最好使用普通的同步函数,这样可以避免使用承诺.

This behaviour might be engine dependant, so I would not rely on this behaviour. A Promise instance is a promise of an eventual value and should be treated as such. Never expect a promise to resolve immediately. If you expect a fulfilled promise you are better of using a normal synchronous function, which avoids the use of promises.

这篇关于真的很困惑从异步函数返回的承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆