How to wait for a function, which contains promises

Viewed 495

If we have this function

const getData = () => {
  foo()
  .then(result => {
     return result;
   })
  .catch(error => {
     return error;
   });
};

Although getData is not a promise itself, but it contains a promise, which is asyncrnous.

So what is the best way to wait for getData to return something. Async / Await doesn't work cause they work with promises.

Thanks.

3 Answers

Currently, getData() doesn't return anything. You need to make it return a Promise, so you can await it or chain .then() to it.

const getData = () => {
  return foo() // <-- here
  .then(result => {
     return result;
   })
  .catch(error => {
     throw error;
   });
};

// Now you can do :
getData().then(...)
// or :
const data = await getData();

In this case, you can also omit the curly braces and the explicit return, and make it implicit :

const getData = () => foo()
  .then(result => {
     return result;
   })
  .catch(error => {
     throw error;
   });

Hey but what's that :

.then(result => {
         return result;
})

This does nothing. It takes a value and simply returns it without doing anything. You can remove it.

You can now rewrite getData() this way :

const getData = async () => {
    try {
      return await foo()
    } catch (error) {
      throw error;
    }
}

For that matter, this :

.catch(error => { throw error; });

or this :

catch (error) { throw error; }

are also pretty useless, they just "relay" (bubble up) the error that has to be caught in the calling function.

Now it's obvious getData does pretty much only one thing, it's returning foo(), which is a Promise. It's only a wrapper around a Promise... so it's actually pretty useless.

Bottom line, detData() is useless altogether. foo is a Promise; writing a function that returns a Promise so you can use it like a Promise is just... a Promise with an extra step. Just use foo directly.

let result;
try {
  result = await foo();
} catch (error) {
  console.log(error);
}
console.log(result);

This will not work because getData is not returning a value. You can add a return statement before foo call and wait for the return value.

const getData = () => {
  return foo();
};

getData().then(data => {
  console.log(data);
}).catch(err => {
  console.log(err);
});

To wait for an operation you must return a Promise or use a callback. The code snippet below runs and should illustrate how this works. I implemented a sample foo function that is actually asynchronous (wait for 1 second before returning the data '12345'). I used async/await to illustrate how that can work, but you can equally return the result of foo and use then instead.

const foo = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve('12345'), 1000);
  });
}
const getData = async () => {
  const data = await foo();
  console.log(`Data is ${data}`);
  return data;
};

getData()
  .then(() => console.log('complete'))
  .catch(err => console.log(`oops: ${err}`));
  
console.log('this prints first since async operation is still pending');

Related