Difference of using async / await vs promises?

15,815

Solution 1

async/await and promises are closely related. async functions return promises, and await is syntactic sugar for waiting for a promise to be resolved.

The only drawback from having a mix of promises and async functions might be readability and maintainability of the code, but you can certainly use the return value of async functions as promises as well as await for regular functions that return a promise.

Whether you choose one vs the other mostly depends on availability (does your node.js / browser support async?) and on your aesthetic preference, but a good rule of thumb (based on my own preference at the time of writing) could be:

If you need to run asynchronous code in series: consider using async/await:

return asyncFunction()
.then(result => f1(result))
.then(result2 => f2(result2));

vs

const result = await asyncFunction();
const result2 = await f1(result);
return await f2(result2);

If you need nested promises: use async/await:

return asyncFunction()
.then(result => {
  return f1(result)
  .then(result2 => f2(result, result2);
})

vs

const result = await asyncFunction();
const result2 = await f1(result);
return await f2(result, result2);

If you need to run it in parallel: use promises.

return Promise.all(arrayOfIDs.map(id => asyncFn(id)))

It has been suggested you can use await within an expression to await multiple tasks like so:
*note, this still awaits in sequence from left to right, which is OK if you don't expect errors. Otherwise the behaviour is different due to fail fast behaviour of Promise.all()

const [r1, r2, r3] = [await task1, await task2, await task3];

(async function() {
  function t1(t) {
    console.time(`task ${t}`);
    console.log(`start task ${t}`);
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.timeEnd(`task ${t}`);
        resolve();
      }, t);
    })
  }

  console.log('Create Promises');
  const task1 = t1(100);
  const task2 = t1(200);
  const task3 = t1(10);

  console.log('Await for each task');
  const [r1, r2, r3] = [await task1, await task2, await task3];

  console.log('Done');
}())

But as with Promise.all, the parallel promises need to be properly handled in case of an error. You can read more about that here.

Be careful not to confuse the previous code with the following:

let [r1, r2] = [await t1(100), await t2(200)];

function t1(t) {
  console.time(`task ${t}`);
  console.log(`start task ${t}`);
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.timeEnd(`task ${t}`);
      resolve();
    }, t);
  })
}
console.log('Promise');
Promise.all([t1(100), t1(200), t1(10)]).then(async() => {

  console.log('Await');
  let [r1, r2, r3] = [await t1(100), await t1(200), await t1(10)]
});

Using these two methods is not equivalent. Read more about the difference.

In the end, Promise.all is a cleaner approach that scales better to an arbitrary number of tasks.

Solution 2

Actually it depends on your node version, But if you can use async/await then your code will be more readable and easier to maintain. When you define a function as 'async' then it returns a native Promise, and when you call it using await it executes Promise.then.

Note: Put your await calls inside a try/catch, because if the Promise fails it issues 'catch' which you can handle inside the catch block.

try{
let res1 = await your-async-function(parameters);
let res2 = await your-promise-function(parameters);
await your-async-or-promise-function(parameters);
}
catch(ex){
// your error handler goes here
// error is caused by any of your called functions which fails its promise
// this methods breaks your call chain
}

also you can handle your 'catch' like this:

let result = await your-asyncFunction(parameters).catch((error)=>{//your error handler goes here});

this method mentioned does not produce an exception so the execution goes on.

I do not think there is any performance difference between async/await other than the native Promise module implementation.

I would suggest to use bluebird module instead of native promise built into node.

Solution 3

At this point the only reason to use Promises is to call multiple asynchronous jobs using Promise.all() Otherwise you’re usually better with async/await or Observables.

Solution 4

Its depending upon what approach you are good with, both promise and async/await are good, but if you want to write asynchronous code, using synchronous code structure you should use async/await approach.Like following example, a function return user with both Promise or async/await style. if we use Promise:

function getFirstUser() {
    return getUsers().then(function(users) {
        return users[0].name;
    }).catch(function(err) {
        return {
          name: 'default user'
        };
    });
}

if we use aysnc/await

async function getFirstUser() {
    try {
        let users = await getUsers();
        return users[0].name;
    } catch (err) {
        return {
            name: 'default user'
        };
    }
}

Here in promise approach we need a thenable structure to follow and in async/await approach we use 'await' to hold execution of asynchronous function.

you can checkout this link for more clarity Visit https://medium.com/@bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8

Share:
15,815

Related videos on Youtube

MisterniceGuy
Author by

MisterniceGuy

Updated on June 13, 2022

Comments

  • MisterniceGuy
    MisterniceGuy almost 2 years

    I am looking for a answer on what to use in my nodeJS app.

    I have code which handles my generic dB access to mssql. This code is written using an async functions and then I used a promise to call that function and all works fine.

    As my app is getting bigger and code larger I am planning to move some of the logic into functions and then call them.

    So my question is: is there a drawback to using a mix of async/await and promises or does it really not matter?

    Async / await makes it easier to write more readable code as I have to read and write to multiple db’s before I return something and I need results of some of these.

    So the question is what is the better approach? Async / await on dB layer that’s set and can’t change The logic layer async / await which would allow me a async / and await on the function call or if I go with promise for logic then I am stuck with promise on function call.

    So I hope someone can give me more insight if one has more advantages than the other, besides being able to write cleaner code.

    • Akber Iqbal
      Akber Iqbal over 5 years
      this article highlights some advantages of async/await over promises... hackernoon.com/… - but I would love to find out if there are any performance improvements of using one method over the other...
    • XaxD
      XaxD over 5 years
      @Alqbal there are no performance improvements over async/await.
    • jfriend00
      jfriend00 over 5 years
      async/await only works with promises so there is no async/await OR promises, there's only async/await AND promises. So, really you're asking whether you use just plain promises or promises with async/await.
    • Manngo
      Manngo over 2 years
      Can we clear up something important? async / await are all about promises, so the question, as worded, is misleading. The await statement waits for a promise to be fulfilled. What you’re really asking is about using await vs the then() method. And the short answer is that it is mostly a matter of taste, as they do the same job.
  • Asaf Aviv
    Asaf Aviv over 5 years
    You can use Promise.all() with async/await. const [p1, p2, p3] = await Promise.all([p1(), p2(), p3()]);
  • XaxD
    XaxD over 5 years
    p1,p2,p3 are all classic promises in that instance. If you awaited each of them individually they would be executed synchronously.
  • Asaf Aviv
    Asaf Aviv over 5 years
    They all executing concurrently. We dont wait for one to finish before we call the next one.. We just wait for all to finish with Promise.all().
  • XaxD
    XaxD over 5 years
    Exactly. But if you called await p1(), await p2, await p3, they would be concurrent. p1-p3 have to be declared as explicit promises.
  • Qwerty
    Qwerty about 5 years
    Actually you can hapilly run in parallel using await let [r1, r2] = [await task1, await task2]. Look stackoverflow.com/questions/35612428/…
  • lucascaro
    lucascaro about 5 years
    @Qwerty Thanks for the feedback! I'm not sure that's right. Check my edit and the linked answer. Does that make sense? If I'm mistaken please let me know!
  • Mayank Raj
    Mayank Raj about 5 years
    @lucascaro I have a doubt. Doesn't await makes the code blocking as compared to using then ?
  • lucascaro
    lucascaro about 5 years
    In a sense, you could think of it that way, await "pause" the current function until the promise is resolved, but since this function is asynchronous, it will not block anything outside of the current function.
  • Zantier
    Zantier almost 5 years
    Your code doesn't reflect what @Qwerty was suggesting (it's clearer if you follow the link). task1 and task2 are promises, so they are already running in parallel. Instead of [await t1(100), await t1(200), await t1(10)], you'll need to first call each t1() before using await. A longwinded way is let task1 = t1(100); let task2 = t1(200); let task3 = t1(10); let [r1, r2, r3] = [await task1, await task2, await task3];. But it makes sense to use Promise.all in async/await code, as await simply expects a Promise: let [r1, r2, r3] = await Promise.all([t1(100), t1(200), t1(10)]);
  • XaxD
    XaxD about 4 years
    1 is true with both Promises and Async Await
  • XaxD
    XaxD about 4 years
    can you elaborate on 3?
  • David Spector
    David Spector about 4 years
    I based #3 on something I read that I can no longer find. In fact, jakearchibald.com/2017/async-iterators-and-generators, from almost 3 years ago with Chrome, would indicate that async works fine with iterators. I don't know if this article is still valid for Chrome and other browsers, and I don't have time to try out this asynchronous technology.
  • Asker
    Asker over 3 years
    This answer would be more helpful if it explained why or how one is better with async/await or Observables. As written, it doesn't seem very helpful to one who isn't already familiar with these topics.
  • XaxD
    XaxD over 3 years
    @Asker It's a TL;DR for lucascaro's answer, which is much more thorough.