Difference of using async / await vs promises?

后端 未结 5 1572
Happy的楠姐
Happy的楠姐 2020-12-03 08:42

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

相关标签:
5条回答
  • 2020-12-03 09:00

    Yesterday I made a tentative decision to switch from using Promises to using Async/Await, independent of nodejs, based on the difficulty in accessing previous values in the Promise chain. I did come up with a compact solution using 'bind' to save values inside the 'then' functions, but Async seemed much nicer (and it was) in allowing direct access to local variables and arguments. And the more obvious advantage of Async/Await is, of course, the elimination of the distracting explicit 'then' functions in favor of a linear notation that looks much like ordinary function calls.

    However, my reading today uncovered problems with Async/Await, which derail my decision. I think I'll stick with Promises (possibly using a macro preprocessor to make the 'then' functions look simpler) until Async/Await gets fixed, a few years from now.

    Here are the problems I found. I'd love to find out that I am wrong, that these have easy solutions.

    1. Requires an outer try/catch or a final Promise.catch(), otherwise errors and exceptions are lost.

    2. A final await requires either a Promise.then() or an extra outer async function.

    3. Iteration can only be properly done with for/of, not with other iterators.

    4. Await can only wait for only one Promise at a time, not parallel Promises like Promise chains with Promise.all.

    5. Await doesn't support Promise.race(), should it be needed.

    0 讨论(0)
  • 2020-12-03 09:01

    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

    0 讨论(0)
  • 2020-12-03 09:13

    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.

    0 讨论(0)
  • 2020-12-03 09:13

    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.

    0 讨论(0)
  • 2020-12-03 09:18

    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.

    0 讨论(0)
提交回复
热议问题