Just_Ice
Just_Ice

Reputation: 563

Javascript promise.all()

I have this piece of code.

function a() {
  var promise1 = Promise.resolve(3);
  var promise2 = 42;
  var promise3 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 2000, 'foo');
  });

  Promise.all([promise1, promise2, promise3]).then(function(values) {
    console.log("done", values);
  });
}

async function b() {
 await a(); 
}

b();
console.log("here")

Here, we get the output

"here"

and then after two seconds, we get

"done" Array [3, 42, "foo"]

How do I change this code so that inside function b(), we are actually waiting for a() to complete and then continue the execution of the code?

Hence, the output I want is

Wait two seconds and see

"done" Array [3, 42, "foo"]

"here"

Upvotes: 0

Views: 123

Answers (4)

Pratyush Sharma
Pratyush Sharma

Reputation: 257

You can write the above code like this:

function a() {
    var promise1 = Promise.resolve(3);
    var promise2 = 42;
    var promise3 = new Promise(function (resolve, reject) {
        setTimeout(resolve, 2000, 'foo');
    });

    // Promise.all([promise1, promise2, promise3]).then(function (values) {
    //     console.log("done", values);
    // });

    return Promise.all([promise1, promise2, promise3]);
}

async function b() {
    let values = await a();
    console.log('done', values);
    // return values; // This will get automatically get wrapped into a promise.
    return Promise.resolve(values);
}

b().then(() => { console.log("here") });

Here a returns a promise and after that b also returns a promise which is immediately resolved.

Upvotes: 1

vipul patel
vipul patel

Reputation: 736

Your promise always runs asynchronously so that you have to wait until it get resolved and then you can print your "here" console.

function a() {
  var promise1 = Promise.resolve(3);
  var promise2 = 42;
  var promise3 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 2000, 'foo');
  });

  return Promise.all([promise1, promise2, promise3]).then(function(values) {
   return values;
  });
}

 function b() {
 a().then( function(res) {
  console.log("done", res);
  console.log("here")
 })
}

b();

Upvotes: 1

fxnoob
fxnoob

Reputation: 176

b is the async function. So either you can put await front while calling it then execute rest or do the .then like

b().then(res => {
 //rest codes  
 console.log("here")
})

By the way that is not required to put await in front of promise2 as thats not even a promise object.

Upvotes: 1

E. Zacarias
E. Zacarias

Reputation: 647

You can do it in more than one way.

Form 1

First, because a doesn't return, as stated by @chris-p-bacon, instead of handling the Promise itself, you can return it.

Instead of

Promise.all([promise1, promise2, promise3]).then(function(values) {
  console.log("done", values);
});

use

return Promise.all([promise1, promise2, promise3]);

Form 2

The other way is to make the a function an async function, and then await for the Promise.all, this way:

async function a() {
  ...

  await Promise.all([promise1, promise2, promise3]);
}

In this second form, different than the first form, you can still handle the Promise after it returns:

async function a() {
  ...

  var values = await Promise.all([promise1, promise2, promise3]);
  console.log("done", values);
}

Conclusion

Both forms answer your request to change your piece of code, and it will be almost equivalent to your code. But notice that if you were using the catch function you would have to use a try-catch instead, around the await.

Upvotes: 1

Related Questions