0

Confused with the best practises.

Using async-await is better than using promises. Is it right ?

How to determine the use of aync/await and promises ?

Below I just wrote two code snippets. One with using aync/await and another without it.

Which will be faster?

What is the advantage of CASE 1 ?

Which is newest method and advantage over another ?

CASE 1

var promise1 = rp('https://api.example.com/endpoint1');
var promise2 = rp('https://api.example.com/endpoint2');

var response1 = await promise1;
var response2 = await promise2;
return response1 + ' ' + response2;

CASE 2

var promise1 = rp('https://api.example.com/endpoint1');
var promise2 = rp('https://api.example.com/endpoint2');

return Promise.all([promise1, promise2])
.then(function(values){
    return values[0] + values[1];
});
7
  • 4
    async/await is for Promises not vs Promises Commented Jul 29, 2019 at 12:16
  • Can you please review the two cases and what's the difference between them? Commented Jul 29, 2019 at 12:17
  • Async/await is just fancy syntax to write promises. So most will come down to preference. Case 1 is shorter to write. Case 2 makes it harder to miss that the function is async. I'm one of those people who finds promise chains easier to follow. Commented Jul 29, 2019 at 12:19
  • 3
    @slideshowp2 — No. The promises are both initialised before either is awaited. They will execute in parallel in both cases. Commented Jul 29, 2019 at 12:20
  • Your cases are almost identical. But if you did var r1 = await rp('https://api.example.com/endpoint1'); var r2 = await rp('https://api.example.com/endpoint2') The behaviour would be different: requests would run sequentually. Commented Jul 29, 2019 at 12:20

5 Answers 5

5

Using async-await is better than using promises

No. async and await are tools to help you manage promises.

Which will be faster?

There's unlikely to be any noticeable difference

What is the advantage of CASE 1 ?

Some people would consider it simpler and easier to understand. Others might disagree.

Sign up to request clarification or add additional context in comments.

13 Comments

In the CASE 2 , executing promises in parellel. In CASE 1 one after another.
response2 will get only after getting response1. Is it write ?
@AshwanthMadhav — No. They execute in parallel in both cases. The async process begins when rp() is called. That function returns a promise. The calling function goes to sleep when the await statement is reached. That is after both calls to rp. i.e. it doesn't go to sleep before the second call to rp() so there is no delay in the second async process starting.
Currently I'm working with the same concept as @kuba says. I can't understand the two await working at the same time. When we are consoling after each await line, Before going to this line var response2 = await promise2;, I can print the result of respons12
|
2

Async/await is translated into a Promise under the hood.

Hence, the performance of both is the same.

You should always use async/await, unless there's some technical limitation, as it's easier to understand.

Now, as other mentioned, two code examples are not equal at the moment. But since you're using await, it means that your rp() returns a promise. So, you could rewrite your first case as:

let [r1, r2] = await Promise.all([promise1, promise2])
return r1 + r2

To achieve same results.

4 Comments

In the CASE 2 , executing promises in parellel. In CASE 1 one after another. response2 will get only after getting response1. Is it write ?
You can rewrite your function that uses async/await in the same manner. I updated my answer to demonstrate it.
I got your answer. But could you please explain the difference of case 1 and case 2. Most of them are saying, ith has equal performance.
Your code seems to be good one. When using await for promise1 and promise2 makes a time. Is it Right?
0

Using async-await is better than using promises.

Which will be faster?

Which is newest method and advantage over another?

Neither syntax nor either of your approaches offers any particular advantage over the other, but additionally, your approaches don't display your intent well. You don't need to keep explicit references to the promises in order to get their results concurrently:

const [response1, response2] = await Promise.all([
  rp('https://api.example.com/endpoint1'),
  rp('https://api.example.com/endpoint2')
]);
...

Keep in mind the above approach must be contained within an async function. It cannot exist at top-level scope like this approach:

Promise.all([
  rp('https://api.example.com/endpoint1'),
  rp('https://api.example.com/endpoint2')
]).then(([response1, response2]) => {
  ...
});

4 Comments

But for when using await the next line is executed after getting the result only. There is two awaits. So waiting for both responses. Promise.All doing the things in parallel. Then how async become better? Is it just for understanding?
@AshwanthMadhav There is two awaits. I'm not quite sure what you mean there. There's only one await. Then how async become better? It doesn't. It's a matter of style preference. Use whichever approach makes your code more readable and easier to understand, there is virtually no performance difference, and certainly no difference that you should care about between these two examples other than style.
When consoling under response1, there is the result of that promise. same way, When consoling under response2, there is a result. But there is a time for resolving both the promises
@AshwanthMadhav your comment still doesn't make sense. Are you talking about the example I provided or no?
0

Await is used to evaluate a resolved or rejected Promise. So the functionality is the same using .then and await. However await makes for way more readable code as you don't get into a a series of callbacks. With await you can rather treat your async function as a sync function using await.

Let us take an example. We have an API and 2 databases, we want to take a name from one of the databases and insert into another database. For us to do that we would have to fetch the data from Database 1. Wait for it to arrive to our client to then send it over with a POST request to our API to insert. [ You could do all of this with ONE function server side but for our case we are going to make 2 async fetch request to answer this question ]. If we wanted to solve this using .then in a function it would look something like this.

function get_and_set(){
   fetch("https://www.some_api.com/get_random_name")
   .then( response => response.text() )
     .then( name => {
       fetch("https://www.some_api_2.com/insert_name", {
        headers : {
          "Body-Type"    : "application/json",
          "Accept"       : "application/json"
        },
        method : "POST",
        body : JSON.stringify({ name : name })
      })
      .then( set_response => set_response.text() )
        .then( set_response => {
           return set_response;
        })
     )}

}

If we instead were to choose to use an async function with await we could write as this instead. Which becomes more readable in my personal opinion.

async function get_and_set(){
  let response = await fetch("https://www.some_api.com/get_random_name")
  let name = response.text();

  let insert_response = await fetch("https://www.some_api_2.com/insert_name", {
     headers : {
        "Body-Type"    : "application/json",
        "Accept"       : "application/json"
     },
     method : "POST",
     body : JSON.stringify({ name : name })
  });
  let success = insert_response.text();

  return (success); //Return the status of how the insertion went
}

1 Comment

it is used when we are using the response of first to use in the second API.
0

All current responses are of course correct but please keep in mind some differences.

Currently in both your solutions promises are invoked in parallel. This might lead to some errors.

Consider such case (slight modifications to your case 1):

var response1 = await rp('https://api.example.com/endpoint1');
var response2 = await rp('https://api.example.com/endpoint2');

return response1 + ' ' + response2;

In above case promise2 will be executed AFTER promise1 finishes executing itself. The result is already known when promise2 is started. Your cases, on the other hand, run them all together in some kind of a race. Therefore if in second call to rp would contain logic that depends on some action that is done in first call to rp, it might lead to unexpected results or even to crash. Good example would be writing and reading to the same file.

Let's consider following example:

function writeToFile()
{
   return new Promise((resolve, reject) => {
      ... // writing to file abc.txt
   };
}

function readFile()
{
   return new Promise((resolve, reject) => {
      ... // reading file abc.txt
   };
}

function raceCondition() 
{
   Promise.all([
       writeToFile(),
       readFile()
   ]);
} 

async function asyncAwait() 
{
   await writeToFile();
   await readFile();
} 

raceCondition() function might lead to unexpected behavior because readFile might be run while writeToFile function did not even finish writing to the file. It could lead to reading some old data, or even file might not even exist.

asyncAwait() function uses async/await approach that guarantees that writeToFile() function finishes its work before reading starts. Of course it does not mean that the program becomes synchronous. In the meantime other operations are performed (i.e. some GUI events processing etc).

Async/Await should be then considered as an alternative to .then().then() chain rather than to Promise.all

2 Comments

Here the readFile is executed only after writeToFile. In my case, there is no need to get one after another. Both will execute parallelly may better for me. Both functions are independent.
Yes, you are right, just wanted to pinpoint the possible pitfall in using Promise.all

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.