Node Async/await With Promise.all
Solution 1:
The problem is that asyncOperation2()
and asyncOperation3()
return a promise
(because of their async
declaration) that has no resolved value (thus it's undefined
) because those functions don't have their own return value.
asyncOperation2: asyncfunction (time) {
setTimeout(function () {
return time; // this just returns back into the timer sub-system
}, time);
// there is no return value for your function here// thus the promise the async function returns has an undefined resolved value
},
Returning from inside the setTimeout()
isn't the function's return value. That's just a return back into the timer innards that happens long after the function itself has returned. Remember, setTimeout()
is non-blocking. It schedules some code to run sometime in the future and then returns immediately and your function then finishes and returns (before setTimeout()
has fired). So, then sometime later, your setTimeout()
fires and you return a value from that callback and that value just goes back into the timer sub-system, not to any of your code or to any promise.
Change those two functions to this:
functiondelay(t, v) {
returnnewPromise(resolve => {
setTimeout(resolve.bind(null, v));
}, t);
}
asyncOperation2: function (time) {
returndelay(time, time);
},
asyncOperation3: function (time) {
returndelay(time, time);
},
Now you have functions that return a promise that is resolved with the desired value. Note, there's no need for them to be declared async
either since you aren't using await
inside the functions and you're already creating your own promise to return.
Solution 2:
asyncOperation2
and asyncOperation3
should resolve a promise if you want to some value to be returned. (what you're doing in combine2and2
).
ps. returning some value from setTimeout
would be wrong. You can't do that
Wrap them in a Promise
and resolve the value you want to return from it.
Something like
constApp = {
total: 0,
init: function () {
// I want to run all 3 operations. (with 2 and 3 happening sequentially)Promise.all([App.asyncOperation1(1000), App.combine2and3()])
.then((total) => {
// then I want to use the result of all 3 operationsconsole.log(`total from top: ${total}`);
})
},
asyncOperation1: function (time) {
returnnewPromise(function (resolve, reject) {
var intervalID = setTimeout(function () {
resolve(time);
}, time);
});
},
asyncOperation2: function (time) {
returnnewPromise(function (resolve, reject) {
setTimeout(function () {
resolve(time);
}, time);
});
},
asyncOperation3: function (time) {
returnnewPromise(function (resolve, reject) {
setTimeout(function () {
resolve(time);
}, time);
})
},
combine2and3: asyncfunction () {
var value2 = awaitApp.asyncOperation2(2000);
var value3 = awaitApp.asyncOperation3(1000);
console.log(`value2: ${value2}`)
console.log(`value3: ${value3}`)
console.log(`summed total ${value2 + value3}`);
return value2 + value3;
},
};
App.init();
Solution 3:
When you return time
in the callback function passed to setTimeout
, you only return in the callback function, not in the outer function. You have to wrap the setTimeout
call in a promise, like in asyncOperation1
. You can also make a helper function to avoid repetition.
constwait = time => newPromise(
resolve =>setTimeout(() =>resolve(time), time)
);
constApp = {
total: 0,
init: function () {
// I want to run all 3 operations. (with 2 and 3 happening sequentially)Promise.all([App.asyncOperation1(1000), App.combine2and3()])
.then((total) => {
// then I want to use the result of all 3 operationsconsole.log(`total from top: ${total}`);
})
},
asyncOperation1: wait,
asyncOperation2: wait,
asyncOperation3: wait,
combine2and3: asyncfunction () {
var value2 = awaitApp.asyncOperation2(2000);
var value3 = awaitApp.asyncOperation3(1000);
console.log(`value2: ${value2}`)
console.log(`value3: ${value3}`)
console.log(`summed total ${value2 + value3}`);
return value2 + value3;
},
};
App.init();
Post a Comment for "Node Async/await With Promise.all"