Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async function versus return New Promise

UPDATE

I have read over a dozen articles on this topic and not one of them addresses this fundamental question. I am going to start listing a resources section at the end of this post.

ORIGINAL POST

My understanding of an async function is it returns a promise.

MDN docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

Inside my program I could write something like:

function testPromise() {
  return new Promise((resolve, reject) => {
    // DO WORK
    reject() // IF WORK FAILS
    resolve() // IF WORK IS SUCCESSFUL        
  })
}

async function mainFunction() {
  let variable
  try {
    variable = await testPromise()
  } catch(e) {
    throw e
  }
  return variable
}

I could also write testPromise as an async function and await that in the same context.

async function testAsyncFunction() {
  //DO WORK AND THROW ERROR IF THEY OCCUR      
}

async function mainFunction() {
  let variable
  try {
    variable = await testAsyncFunction()
  } catch(e) {
    throw e
  }
  return variable
}

Which would be considered best practice? If I wish to create asynchronous operation, should the function use return New Promise and awaited in a async function or is awaiting an async function from an async function the same difference?

RESOURCES

JavaScript ES 2017: Learn Async/Await by Example https://codeburst.io/javascript-es-2017-learn-async-await-by-example-48acc58bad65

Javascript — ES8 Introducing async/await Functions https://medium.com/@reasoncode/javascript-es8-introducing-async-await-functions-7a471ec7de8a

6 Reasons Why JavaScript’s Async/Await Blows Promises Away (Tutorial) https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9

----------------------CURRENT----------------------

export default function time_neo4jUpdate({ store, action, change, args, }) {
  return new Promise(async (resolve, reject) => {
    try {
      const {
        thing: { type },
        nonValidatedArgs: { leapYear, root, start, end },
          _neo4j,
          _cypherReducers,
          _neo4jCreateReduce,
          _timetreeSteps: { update }
      } = store.getState()
      let results = []
      for (let i = 0; i < _neo4jCreateReduce.length; i++) {
        const result = await _neo4j.session(
          _neo4jCreateReduce[i],
          _cypherReducers.runQuery(update, i, root, start, end))
        results = [...results, result]
      }
      resolve({
        store,
        action: 'NEO4J_UPDATE',
        change: results,
        args
      })
    } catch (e) {
      const m = `NEO4J TIMETREE UPDATE: Unable to complete the UPDATE step for the timetree. WHAT: ${e}`
      reject(m)
    }
  })
}

----------------------AS ASYNC FUNCTION----------------------

export default async function time_neo4jUpdate({ store, action, change, args, }) {
  try {
    const {
      thing: { type },
      nonValidatedArgs: { leapYear, root, start, end },
      _neo4j,
      _cypherReducers,
      _neo4jCreateReduce,
      _timetreeSteps: { update }
    } = store.getState()
    let results = []
    for (let i = 0; i < _neo4jCreateReduce.length; i++) {
      const result = await _neo4j.session(
        _neo4jCreateReduce[i],
        _cypherReducers.runQuery(update, i, root, start, end))
      results = [...results, result]
    }
    return {
      store,
      action: 'NEO4J_UPDATE',
      change: results,
      args
    }
  } catch (e) {
    const m = `NEO4J TIMETREE UPDATE: Unable to complete the UPDATE step for the timetree. WHAT: ${e}`
    throw m
  }
}
like image 979
Cazineer Avatar asked Nov 01 '17 03:11

Cazineer


People also ask

Do you need async If you return promise?

Short answer: no, an async function doesn't have to returns a Promise. Actually, generally you wouldn't return a Promise object (unless you're chaining asynchronous events). What async and await do is wait for a response from something that returns a Promise. You first code example actually returns a resolved Promise.

Is async better than promise?

Using Async/Await makes it easier to read and understand the flow of the program as compared to promise chains.

Do async functions automatically return a promise?

Async functions are available natively in Node and are denoted by the async keyword in their declaration. They always return a promise, even if you don't explicitly write them to do so. Also, the await keyword is only available inside async functions at the moment – it cannot be used in the global scope.

How do you create asynchronous function that returns a promise?

Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.


1 Answers

Even without the availability of async/await, you should very rarely need to use new Promise(). If you're using it a lot, it's typically a code smell.

The whole point of async/await is that it allows you to avoid a lot of the situations where you would otherwise need to work with promises explicitly.

So if it's supported in the environment you're targeting (Internet Explorer does not support async/await) or you're using a transpiler, go ahead and use it anywhere you can. That's what it's for.

Bear in mind that this is pointless:

catch(e) {
    throw e;
}

There's no point in catching an error just to rethrow it. So if you're not actually doing anything with the caught error, don't catch it:

async function testAsyncFunction() {
  //DO WORK AND THROW ERROR IF THEY OCCUR
  return value
}

Edit: Now that you've provided an example of your code, I can answer with more certainty: If your function is based upon existing promises, then by all means, it is good to use async/await and you usually should not use new Promise():

export default async function time_neo4jUpdate({
    store,
    action,
    change,
    args,
  }) {
    try {
      const {
        thing: {
          type
        },
        nonValidatedArgs: {
          leapYear,
          root,
          start,
          end
          },
          _neo4j,
          _cypherReducers,
          _neo4jCreateReduce,
          _timetreeSteps: {
            update
        }
      } = store.getState()

      const results = await _neo4jCreateReduce.reduce(async function (acc, el) {
        const result = await _neo4j.session(
          el,
          _cypherReducers.runQuery(
            update,
            i,
            root,
            start,
            end
          )
        )

        return [...(await acc), result]
      }, []);

      return {
        store,
        action: 'NEO4J_UPDATE',
        change: results,
        args
      };
    } catch (e) {
      const m = `NEO4J TIMETREE UPDATE: Unable to complete the UPDATE step for the timetree. WHAT: ${e}`
      throw m;
    }
}
like image 135
JLRishe Avatar answered Sep 20 '22 08:09

JLRishe