sensorario
sensorario

Reputation: 21698

is this Promise to async convertion correct and why await is not necessary?

I've this snippet of code with a promise.

function f (number) {
  return new Promise((resolve, reject) => {
    if (number === 42) {
      resolve({ success : "bar" })
    }

    reject({ bar : "foo" })
  })
}

f(42)
  .then(success)
  .catch(bar);

f(43)
  .then(success)
  .catch(bar);

function success(input) {
  console.log(input)
}

function bar() {
  console.log("marianna")
}

and the following it the attempt to convert a promise to async/await syntax:

async function f (number) {
    if (number === 42) {
      return { success : "bar" }
    }

    throw { bar : "foo" }
}

f(42)
  .then(success)
  .catch(bar);

f(43)
  .then(success)
  .catch(bar);

function success(input) {
  console.log(input)
}

function bar() {
  console.log("marianna")
}

The output given from both scripts is equal. I think convertion is correct but I still got difficulties to "read" async code.

Anyway, .. why await is not necessary? When does await is required?

Upvotes: 1

Views: 41

Answers (3)

jonathangersam
jonathangersam

Reputation: 1147

I think conversion is correct but I still got difficulties to "read" async code.

I have 2 things I think about when deciding on async/await vs then/catch syntax:

  1. Should it run on installations with NodeJS lower than version 7.6? If yes, we can only use Promise then/catch as async/await starts with v7.6 NodeJS 7.6 support for async/await.
  2. Which version would read cleaner to the next person maintaining my code?.

I use async/await when I think a section of code would read cleaner as a sequence of procedures in a try/catch block.

async-await-test.js

main()

/* test body */
async function main() {
  try {
    const result = await pingMeAfterOneSecond(true)
    console.log('RESOLVED with ', result)
  } catch (e) {
    console.log('REJECTED due to', e)
  }
}

/* some function that will resolve or reject as requested after 1 second -- this is same as in then-catch-test.js */
function pingMeAfterOneSecond(willSucceed) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (willSucceed) {
        resolve(true)
      } else {
        reject(false)
      }
    }, 1000)
  })
}

I use then/catch when I think a section of code would be in danger of looking like a nested spaghetti of try/catch blocks.

then-catch-test.js

/* test body */
pingMeAfterOneSecond(true)
  .then(result => console.log('RESOLVED with ', result))
  .catch(e => console.log('REJECTED due to', e))

/* some function that will resolve or reject as requested after 1 second -- this is same as in try-catch-test.js */
function pingMeAfterOneSecond(willSucceed) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (willSucceed) {
        resolve(true)
      } else {
        reject(false)
      }
    }, 1000)
  })
}

Hope this helps you think through the choices. Cheers,

Upvotes: 0

deerawan
deerawan

Reputation: 8443

await can improve code reading. It treats asynchronous function call looks like synchronous call.

In your example, let's say if I want to run f(43) after f(42) finish. For this case, I can do like this below

f(42)
  .then(() => {
    success(); 
    return f(43);
  })
  .then(success) 
  .catch(bar);

comparing to await

async function f (number) {
    if (number === 42) {
      return { success : "bar" }
    }

    throw { bar : "foo" }
}

async function run() {
  try {
    const result42 = await f(42); // async function but called like sync function
    success(result42); 
    
    const result43 = await f(43);
    success(result43);
  } catch(error) {
    bar(error);
  }
}

run();

function success(input) {
  console.log(input)
}

function bar() {
  console.log("marianna")
}

Upvotes: 1

axiac
axiac

Reputation: 72366

A Promise is an object that represents an eventual completion or failure of an asynchronous operation.

There is nothing asynchronous in your code, both versions of function f() return a Promise that is already resolved or rejected. However, this does not change the way async/await works.

Using async and await your code should look like this:

async function f (number) {
    if (number === 42) {
      return { success : "bar" }
    }

    throw { bar : "foo" }
}

try {
    res = await f(42)
    success(res)
} catch(err) {
    bar(err);
}

try {
    res = await f(43)
    success(res)
} catch(err) {
    bar(err);
}

function success(input) {
  console.log(input)
}

function bar(err) {
  console.log(`error: ${err}`)
}

Behind the scenes, both versions of the code run the same way. But usually the async/await version is easier to read because the code is laid out the same way as synchronous code, with await in front of the asynchronous operations.

Upvotes: 0

Related Questions