简体   繁体   English

异步 function - 等待不等待 promise

[英]async function - await not waiting for promise

I'm trying to learn async-await.我正在尝试学习异步等待。 In this code -在这段代码中 -

const myFun = () => {
    let state = false;

    setTimeout(() => {state = true}, 2000);

    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if(state) {
                resolve('State is true');
            } else {
                reject('State is false');
            }
        }, 3000);
    });
}

const getResult = async () => {
    return await myFun();
}

console.log(getResult());

why am I getting output as -为什么我得到 output 作为 -

Promise { <pending> }

Instead of some value?而不是一些价值? Shouldn't the getResult() function wait for myFun() function resolve it's promise value? getResult() function 不应该等待myFun() function 解析它的 promise 值吗?

If you're using async/await, all your calls have to use Promises or async/await.如果您使用的是 async/await,则所有调用都必须使用 Promises 或 async/await。 You can't just magically get an async result from a sync call.您不能只是从同步调用中神奇地获得异步结果。

Your final call needs to be:您的最终电话需要是:

getResult().then(response => console.log(response));

Or something like:或类似的东西:

(async () => console.log(await getResult()))()

What you need to understand is that async/await does not make your code run synchronously, but let's you write it as if it is:您需要了解的是,async/await 不会让您的代码同步运行,而是让您将其编写为:

In short: The function with async in front of it is literally executed asynchronously, hence the keyword "async".简而言之:前面带有 async 的函数实际上是异步执行的,因此使用了关键字“async”。 And the "await" keyword wil make that line that uses it inside this async function wait for a promise during its execution.并且“await”关键字将使在此异步函数中使用它的那行在其执行期间等待承诺。 So although the line waits, the whole function is still run asynchronously, unless the caller of that function also 'awaits'...因此,尽管线路等待,但整个函数仍然异步运行,除非该函数的调用者也“等待”......

More elaborately explained: When you put async in front of a function, what is actually does is make it return a promise with whatever that function returns inside it.更详细的解释:当你把 async 放在一个函数前面时,实际上是让它返回一个带有该函数返回的任何内容的 Promise。 The function runs asynchronously and when the return statement is executed the promise resolves the returning value.该函数异步运行,当执行 return 语句时,promise 会解析返回值。

Meaning, in your code:意思是,在您的代码中:

const getResult = async () => {
    return await myFun();
}

The function "getResult()" will return a Promise which will resolve once it has finished executing.函数“getResult()”将返回一个 Promise,一旦它完成执行就会解决。 So the lines inside the getResult() function are run asynchronously, unless you tell the function calling getResult() to 'await' for it as well.所以 getResult() 函数内的行是异步运行的,除非你告诉调用 getResult() 的函数也为它“等待”。 Inside the getResult() function you may say it must await the result, which makes the execution of getResult() wait for it to resolve the promise, but the caller of getResult() will not wait unless you also tell the caller to 'await'.在 getResult() 函数中,您可能会说它必须等待结果,这使得 getResult() 的执行等待它解决 promise,但 getResult() 的调用者不会等待,除非您也告诉调用者“等待” '。

So a solution would be calling either:所以一个解决方案是调用:

getResult().then(result=>{console.log(result)})

Or when using in another function you can simply use 'await' again或者在另一个函数中使用时,您可以简单地再次使用“等待”

async callingFunction(){
    console.log(await(getResult());
}

This is my routine dealing with await and async using a Promise with resolve and reject mechanism这是我使用带有解析拒绝机制的Promise处理等待异步的例程

    // step 1 create a promise inside a function
    function longwork()
    {
        p =  new Promise(function (resolve, reject) {
            result = 1111111111111 // long work here ; 

            if(result == "good"){
                resolve(result);
            }
            else
            {
                reject("error ...etc")
            } 
        })

        return p
    }

    // step 2 call that function inside an async function (I call it main)and use await before it
    async function main()
    {
         final_result = await longwork();
         //..

    }  

    //step 3 call the async function that calls the long work function
    main().catch((error)=>{console.log(error);})

Hope that saves someone valuable hours希望可以节省一些宝贵的时间

There is no point to async and await when this is the actual case:在实际情况下,异步和等待没有意义:

Promise.resolve(3).then(console.log); console.log(4);
4
3

In other words, since the then() forks and runs slower than the subsequent statements (even for a resolved Promise) then we need to put the subsequent statements inside the then, like:换句话说,由于 then() fork 和运行比后续语句慢(即使对于已解决的 Promise),那么我们需要将后续语句放在 then 中,例如:

Promise.resolve(3).then(_ => { console.log(_); console.log(4); });
3
4

And since that is true then why bother to await.既然这是真的,那为什么还要等待。 So Im yet to see why async and await even exist.所以我还没有看到为什么 async 和 await 存在。

What hasn't been mentioned in this discussion are the use-case implications of the behaviour.本次讨论中未提及的是该行为的用例含义。 The key thing, as I see it, is to consider what you are planning to do with the output from the top level, truly asynchronous function, and where you are planning to do that.在我看来,关键是要考虑您打算从顶层对 output 做什么,真正异步的 function,以及您打算在哪里做。

If you are planning to consume the output immediately, ie within the "async" function that is awaiting the return of the top level asynchronous function, and what you do with the output has no implication for other functions deeper in the call stack, then it does not matter that the deeper functions have moved on.如果您计划立即使用 output,即在等待顶级异步 function 返回的“异步”function 中,并且您对 output 所做的操作对调用堆栈中更深层的其他函数没有任何影响,那么它更深层次的功能已经转移并不重要。 But if the output is needed deeper in the call stack, then you need use "async" functions making await calls all the way down the stack to that point.但是如果 output 需要在调用堆栈的更深处,那么您需要使用“异步”函数在堆栈中一直等待调用到该点。 Once you reach a point in the call stack where the function does not care about the asynchronous output, then you can stop using async functions.一旦您到达调用堆栈中 function 不关心异步 output 的点,您就可以停止使用异步函数。

For example, in the following code, function B uses the stuff returned from function A so is declared "async" and awaits A().例如,在下面的代码中,function B 使用从 function A 返回的内容,因此被声明为“async”并等待 A()。 Function C() calls B(), is returned a Promise, but can move straight on before that promise is resolved because it is not interested in A()'s stuff, nor what's done with it. Function C() 调用 B(),返回 Promise,但可以在 promise 解析之前直接继续,因为它对 A() 的内容不感兴趣,也不关心它做了什么。 So C does not need to be declared as async, nor await B().所以C不需要声明为async,也不需要await B()。

function A() {
    return new Promise((resolve, reject) => {
        //do something slow
        resolve (astuff)
    }
}
async function B() {
    var bstuff = await A();
    dosomethingwith(bstuff);
    return;
}
function C() {
    B();
    dontwaitmoveon();
    ...
    return;
}

In this next example, C() does use A()'s stuff, so needs to wait for it.在下一个示例中,C() 确实使用了 A() 的内容,因此需要等待它。 C() must be declared "async" and await B(). C() 必须声明为“异步”并等待 B()。 However D() does not care about A()'s stuff, nor what's done with it, so moves on once C() returns its promise.然而 D() 不关心 A() 的东西,也不关心它做了什么,所以一旦 C() 返回它的 promise 就继续前进。

function A() {
    return new Promise((resolve, reject) => {
        //do something slow
        resolve (astuff)
    }
}

async function B() {
    var bstuff = await A();
    dosomething();
    return bstuff;
}

async function C() {
    var cstuff = await B();
    dosomethingwith(cstuff);
    ...
    return;
}

function D() {
    C();
    dontwaitmoveon();
    ...
    return;
}

Since figuring this out, I have tried to design my code so the stuff returned by the asynchronous function is consumed as close as possible to the source.自从弄清楚这一点后,我尝试设计我的代码,以便尽可能接近源使用异步 function 返回的内容。

Though your " getResult " function is async and you have rightly made an await call of myFun, look at the place where you call the getResult function, it is outside any async functions so it runs synchronously.尽管您的“ getResult ”函数是异步的,并且您正确地对 myFun 进行了 await 调用,但请查看调用getResult函数的位置,它位于任何异步函数之外,因此它是同步运行的。

So since getResult called from a synchronous point of view, as soon as it is called, Javascript synchronously gets whatever result is available at the moment, which is a promise.所以既然getResult是从同步的角度调用的,那么只要调用,Javascript 就会同步获取当前可用的任何结果,这是一个 Promise。

So returns from an async function cannot be forced to await(very important), since they are synchronously tied to the place of origin of the call.因此,异步函数的返回不能被强制等待(非常重要),因为它们与调用的来源地是同步的。

To get what you want you can run the below,要获得您想要的,您可以运行以下命令,

async function getResult() {
  const result = await myFun();
  console.log(result);
//see no returns here
}
getResult();

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

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