What is the difference between:
async function subfunc(){
await something()
}
async function func(){
subfunc() // subfunc is not awaited but something inside it is
}
func()
and
async function subfunc(){
await something()
}
async function func(){
await subfunc() // subfunc is awaited and something inside it is also
}
func()
It sounds like it produces the same result, where am I wrong?
>Solution :
It sounds like it produces the same result, where am I wrong?
The results are very different.
Without await, the promise returned by subfunc is not awaited, so func settles its promise without waiting for the promise from subfunc to settle. Several ramifications of that:
subfunc‘s work won’t be done yet whenfunc‘s promise is settled.funccan’t use the fulfillment value ofsubfunc‘s promise (though your code usingawaitdoesn’t use it either, so that may not matter to you).- if
subfunc‘s promise is rejected, it doesn’t cause rejection offunc‘s promise;func‘s promise will already be fulfilled. In fact, nothing will handle the rejection ofsubfunc‘s promise, which will at a minimum trigger a console warning about an unhandled rejction or at a maxiumum could terminate the process the code is running in (Node.js does this by default, for instance).
(Re that third one: It happens that in the example you’ve given, nothing is handling rejection of func‘s promise either, but at least code calling func has the opportunity to handle rejection. Without the await of subfunc‘s promise, code calling func can’t avoid a possible unhandled rejection.)
You can see some of that in these two examples (be sure to look int he real browser console):
Without await:
function something(flag) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (flag) {
console.log("`subfunc` promise fulfilled");
resolve();
} else {
console.log("`subfunc` promise rejected");
reject(new Error("Some error here"));
}
}, 100);
});
}
async function subfunc(flag) {
await something(flag);
}
async function func(flag) {
subfunc(flag); // No `await`
}
async function test(flag) {
console.log("-");
console.log(
`Calling \`func\` to test ${flag ? "fulfillment" : "rejection"}:`
);
try {
await func(flag);
console.log("`func` promise fulfilled");
} catch (error) {
console.log("`func` promise rejected: ", error.message);
}
}
console.log("WITHOUT `await`:");
test(true).then(() => {
setTimeout(() => {
test(false);
}, 500);
});
.as-console-wrapper {
max-height: 100% !important;
}
Notice the
Uncaught (in promise) Error: Some error here
or similar in the real browser console. That’s the unhandled rejection.
With await:
function something(flag) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (flag) {
console.log("`subfunc` promise fulfilled");
resolve();
} else {
console.log("`subfunc` promise rejected");
reject(new Error("Some error here"));
}
}, 100);
});
}
async function subfunc(flag) {
await something(flag);
}
async function func(flag) {
await subfunc(flag);
}
async function test(flag) {
console.log("-");
console.log(
`Calling \`func\` to test ${flag ? "fulfillment" : "rejection"}:`
);
try {
await func(flag);
console.log("`func` promise fulfilled");
} catch (error) {
console.log("`func` promise rejected: ", error.message);
}
}
console.log("WITH `await`:");
test(true).then(() => {
setTimeout(() => {
test(false);
}, 500);
});
.as-console-wrapper {
max-height: 100% !important;
}