Returning Promise with an async function

二次信任 提交于 2021-02-04 21:01:36

问题


Given the following two implementations (in ES6 / NodeJS)

async TestFunc() {
    return new Promise((resolve,reject) => {
        ...
    });
}

and

TestFunc() {
    return new Promise((resolve,reject) => {
        ...
    });
}

Is there any difference in behavior if I were to call either of these functions like so?

await TestFunc();

I would assume that the first (async) implementation would return a promise, and we would be awaiting that to return another promise, whereas the latter (synchronous) implementation would return the promise, which then would get awaited. However, they both work as expected, leaving me a bit confused.


回答1:


An async function returns a promise that will be resolved by the value returned by a return statement executed in the function body (or resolved with undefined if returning after executing the last line of function code).

Resolving a promise with a promise makes the resolved promise take on the settled state and value of the resolving promise when and if it becomes settled.

So always synchronously returning a promise P from an async function body on first call immediately links the outcome of the promise returned by calling the async function to the outcome of P. This is an unnecessary step for a synchronously returned promise and the async declaration of the function is not necessary.

If TestFunc is an async function, for

await TestFunc();

the operand of the await operator is the promise generated by calling the async function. This promise will be settled by a promise returned in function body code.

If TestFunc is not an async function, for

await TestFunc();

the operand of the await operator is the promise constructed and returned by the TestFunc. The effective difference is that TestFunc can't internally use the await operator without changing it back to an async function.




回答2:


function TestFunc() {
  return new Promise( resolve => {
    setTimeout(()=>{ resolve(42) }, 5000 );
  });
}

Alright! We have imported @w0f's asynchronous function and have just decided that we want to use it with async/await.

However, one assumption is wrong: That we would need to change @w0f's function to do so.

Instead, we only use the async keyword to allow the use of await inside our own function:

async function run(){
   const value = await TestFunc();
   // Now we can use the value just as if was a normal variable declaration.
   const total = value + 14;
}
run();

The same thing with promises would be:

const promise = TestFunc();
promise.then(value => { 
  const total = value + 14;
});

And anyone new to promises would think "Okay that doesn't look so bad, now we only need to unwrap the value from the promise!". But alas...

const promise = TestFunc();
let total;
promise.then(value => { 
  total = value + 14;
});

// ...it's not possible to unwrap a value from a promise while
// also knowing when the value has resolved - other than checking every now and then:

console.log( total ); // undefined
wait( 3000 );  // wait is a synchronous wait to be implemented by the reader :p
console.log( total ); // undefined
wait( 3000 );
console.log( total ); // 56, yay!

So perhaps you spend a few months to invent some clever and intricate code to check if a value has resolved or not. Congratulations, you have just reinvented promises!

And that's why await is so neat. You are effectively operating on a promise-wrapped value but async/await makes it look like a normal value.



来源:https://stackoverflow.com/questions/50918694/returning-promise-with-an-async-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!