async/await implicitly returns promise? async/await implicitly returns promise? javascript javascript

async/await implicitly returns promise?


The return value will always be a promise. If you don't explicitly return a promise, the value you return will automatically be wrapped in a promise.

async function increment(num) {  return num + 1;}// Even though you returned a number, the value is// automatically wrapped in a promise, so we call// `then` on it to access the returned value.//// Logs: 4increment(3).then(num => console.log(num));

Same thing even if there's no return! (Promise { undefined } is returned)

async function increment(num) {}

Same thing even if there's an await.

function defer(callback) {  return new Promise(function(resolve) {    setTimeout(function() {      resolve(callback());    }, 1000);  });}async function incrementTwice(num) {  const numPlus1 = await defer(() => num + 1);  return numPlus1 + 1;}// Logs: 5incrementTwice(3).then(num => console.log(num));

Promises auto-unwrap, so if you do return a promise for a value from within an async function, you will receive a promise for the value (not a promise for a promise for the value).

function defer(callback) {  return new Promise(function(resolve) {    setTimeout(function() {      resolve(callback());    }, 1000);  });}async function increment(num) {  // It doesn't matter whether you put an `await` here.  return defer(() => num + 1);}// Logs: 4increment(3).then(num => console.log(num));

In my synopsis the behavior is indeed inconsistent with traditionalreturn statements. It appears that when you explicitly return anon-promise value from an async function, it will force wrap it in apromise. I don't have a big problem with it, but it does defy normalJS.

ES6 has functions which don't return exactly the same value as the return. These functions are called generators.

function* foo() {  return 'test';}// Logs an object.console.log(foo());// Logs 'test'.console.log(foo().next().value);


I took a look at the spec and found the following information. The short version is that an async function desugars to a generator which yields Promises. So, yes, async functions return promises.

According to the tc39 spec, the following is true:

async function <name>?<argumentlist><body>

Desugars to:

function <name>?<argumentlist>{ return spawn(function*() <body>, this); }

Where spawn "is a call to the following algorithm":

function spawn(genF, self) {    return new Promise(function(resolve, reject) {        var gen = genF.call(self);        function step(nextF) {            var next;            try {                next = nextF();            } catch(e) {                // finished with failure, reject the promise                reject(e);                return;            }            if(next.done) {                // finished with success, resolve the promise                resolve(next.value);                return;            }            // not finished, chain off the yielded promise and `step` again            Promise.resolve(next.value).then(function(v) {                step(function() { return gen.next(v); });            }, function(e) {                step(function() { return gen.throw(e); });            });        }        step(function() { return gen.next(undefined); });    });}


Your question is: If I create an async function should it return a promise or not? Answer: just do whatever you want and Javascript will fix it for you.

Suppose doSomethingAsync is a function that returns a promise. Then

async function getVal(){    return await doSomethingAsync();}

is exactly the same as

async function getVal(){    return doSomethingAsync();}

You probably are thinking "WTF, how can these be the same?" and you are right. The async will magically wrap a value with a Promise if necessary.

Even stranger, the doSomethingAsync can be written to sometimes return a promise and sometimes NOT return a promise. Still both functions are exactly the same, because the await is also magic. It will unwrap a Promise if necessary but it will have no effect on things that are not Promises.