10

I'm new to javascript and I tried to implement my first async await and can't figure out where is my problem.

getName() - should return a promise after 1s. f() - should wait for getName to finish and then print name

What am I missing ?

const getName = async () => {
  setTimeout(() => 'xxx', 1000)
};

const f = async () => {
  name = await getName()
  console.log(name)
}

f()
Htpc Rad
  • 133
  • 1
  • 1
  • 7
  • The `async` keyword does two things: 1) Makes it possible to use `await` inside the function (which you don't do in `getName`). 2) Makes the function return a Promise no matter what. – Paul Feb 07 '19 at 21:57
  • 1
    It doesn't change behaviour in any way, and since your function without `getName` would just return `undefined`, the async keyword effectively just makes it return `Promise.resolve( undefined )` instead. – Paul Feb 07 '19 at 21:58

2 Answers2

11

Unless you're using await also inside getName, you don't need to have getName async, you just need to return a Promise; since await works with promises:

const getName = () => 
  new Promise(resolve => setTimeout(resolve, 1000, 'xxx'));

async f() {
  let name = await getName();
  console.log(name);
}

f();
ZER0
  • 24,846
  • 5
  • 51
  • 54
  • 2
    The difference is that `async` wraps the `returned` value in a fulfilled promise: "return value of an async function is implicitly wrapped in `Promise.resolve`" (see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function). Therefore you don't have the granularity needed to resolve when something happens (e.g. waiting one second), it will be resolved immediately. Basically those are equivalent: `const a = async () => true` and `const b = () => Promise.resolve(true)`. – ZER0 Feb 08 '19 at 12:18
  • sorry for deleting my question which you answered in this comment ^. Thanks for the answer! – Htpc Rad Feb 08 '19 at 12:22
4

To await a function, that function must return a promise.

You thus need to create a new promise. It will have 2 methods: resolve, and reject.

  1. resolve returns the variable, and is used on success. You can catch its return value by using promise.then(value => ) or by awaiting it.
  2. reject throws an error, and is used on error. You can catch the error by using promise.catch(err => ) or by awaiting the async function and wrapping it in a try-catch block.

Here is how your code should look:

const getName = async () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('xxx');
    }, 1000)
  })
};

const f = async () => {
  name = await getName()
  console.log(name)
}

f()
Azami
  • 2,122
  • 1
  • 12
  • 22
  • 1
    His function was async, so it already returned a Promise, although it was a Promise was immediately resolved with the value `undefined`. – Paul Feb 07 '19 at 21:53
  • You're right, ran some more tests in console and figured that out. Deleted comment instead of editing it and sadly can't bring it back up any more. Edit: this is getting out of hands. – Azami Feb 07 '19 at 22:06