I am studying await promises in node.js
The following program is run by calling main()
at the bottom.
main()
calls the function caller()
. caller()
then calls function loop()
which is a timeout of 2 seconds and return a message I waited 2 sec. loop()
returns to caller()
, then caller()
returns to main()
, merely to pass the same messages.
caller() and main() are practically the same codes and they should return the same way !! But return to main() is undefined.
Eclipse run result:
C:\Users\Lenovo\eclipse-workspace.metadata.plugins\org.eclipse.wildwebdeveloper.embedder.node\node-v14.15.4-win-x64\node.exe awaitPromise2.js " Top Level starts.. main start ... in loop, start aaa : New loop, finished output : Message: I waited 1 sec. in caller aaa : Message: I waited 1 sec. in caller, resolve aaa : Message: I waited 1 sec. in main, response :undefined in main, resolve result : undefined
The program file is:
async function loop() {
let aaa = "New";
console.log("in loop, start aaa : " aaa);
await new Promise((resolve, reject) => setTimeout(resolve, 2000));
aaa = " Message: I waited 2 sec.";
return new Promise((resolve) => {
console.log("loop, finished output : " aaa);
resolve(aaa);
return;
});
}
async function caller() {
await loop().then(function (aaa) {
new Promise((resolve, reject) => setTimeout(resolve, 3000));
console.log("in caller aaa :" aaa);
return new Promise((resolve) => {
new Promise((resolve, reject) => setTimeout(resolve, 1500));
let bbb = aaa;
console.log("in caller, resolve aaa : " bbb);
resolve(bbb);
});
});
}
async function main() {
console.log("main start ...");
await caller().then(function (aaa) {
new Promise((resolve, reject) => setTimeout(resolve, 5000));
console.log("in main, response :" aaa);
return new Promise((resolve) => {
new Promise((resolve, reject) => setTimeout(resolve, 6000));
console.log("in main, resolve result : " aaa);
resolve(aaa);
return;
});
});
}
console.log(" Top Level starts..");
main();
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
I made uses of timeout trying to wait for results to come. Are they needed??
CodePudding user response:
Let's remove all the superfluous stuff from the code that did nothing:
async function loop() {
let aaa = "New";
console.log("in loop, start aaa : " aaa);
await new Promise((resolve, reject) => setTimeout(resolve, 2000));
aaa = " Message: I waited 2 sec.";
console.log("loop, finished output : " aaa);
return Promise.resolve(aaa);
}
async function caller() {
await loop().then(function (aaa) {
console.log("in caller aaa :" aaa);
let bbb = aaa;
console.log("in caller, resolve aaa : " bbb);
return Promise.resolve(bbb);
});
}
async function main() {
console.log("main start ...");
await caller().then(function (aaa) {
console.log("in main, response :" aaa);
console.log("in main, resolve result : " aaa);
return Promise.resolve(aaa);
});
}
console.log(" Top Level starts..");
main();
Now the problem is clear to see: caller
doesn't return
a value. The only return
statement it contains is inside the .then()
callback, resolving the promise that is await
ed, but afterwards nothing happens with that. To fix that, return
the promise chain instead of only await
ing it:
function caller() {
return loop().then(function (aaa) {
console.log("in caller, aaa: " aaa);
return Promise.resolve(aaa);
});
}
Or better don't use .then()
chaining when you can use async
/await
everywhere. Also you can omit Promise.resolve
from return values in async
functions or .then
callbacks:
async function loop() {
const aaa = "New";
console.log("in loop, start: " aaa);
await new Promise((resolve, reject) => setTimeout(resolve, 2000));
const bbb = "Message: I waited 2 sec.";
console.log("loop, finished output: " bbb);
return bbb;
}
async function caller() {
const bbb = await loop();
console.log("in caller:" bbb);
return bbb;
}
async function main() {
console.log("main start ...");
const res = await caller();
console.log("in main, response: " res);
// return res; // unused anyway
}
console.log("Top Level starts...");
main();
CodePudding user response:
Man, you just missed a return
in the caller. Or, you used await
incorrectly. Because you used await
the result is not returned unless return is called.
async function loop() {
let aaa = "New";
console.log("in loop, start aaa : " aaa);
await new Promise((resolve, reject) => setTimeout(resolve, 2000));
aaa = " Message: I waited 2 sec.";
return new Promise((resolve) => {
console.log("loop, finished output : " aaa);
resolve(aaa);
return;
});
}
async function caller() {
return await loop().then(function (aaa) {
new Promise((resolve, reject) => setTimeout(resolve, 3000));
console.log("in caller aaa :" aaa);
return new Promise((resolve) => {
new Promise((resolve, reject) => setTimeout(resolve, 1500));
let bbb = aaa;
console.log("in caller, resolve aaa : " bbb);
resolve(bbb);
});
});
}
async function main() {
console.log("main start ...");
await caller().then(function (aaa) {
new Promise((resolve, reject) => setTimeout(resolve, 5000));
console.log("in main, response :" aaa);
return new Promise((resolve) => {
new Promise((resolve, reject) => setTimeout(resolve, 6000));
console.log("in main, resolve result : " aaa);
resolve(aaa);
return;
});
});
}
console.log(" Top Level starts..");
main();
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
I suggest you do not mix async
with .then
, you should pick one and stick with it.
I suggest you ditch the async/await
in caller()
, it is much easier to understand:
async function loop() {
let aaa = "New";
console.log("in loop, start aaa : " aaa);
await new Promise((resolve, reject) => setTimeout(resolve, 2000));
aaa = " Message: I waited 2 sec.";
return new Promise((resolve) => {
console.log("loop, finished output : " aaa);
resolve(aaa);
return;
});
}
function caller() {
return loop().then(function (aaa) {
new Promise((resolve, reject) => setTimeout(resolve, 3000));
console.log("in caller aaa :" aaa);
return new Promise((resolve) => {
new Promise((resolve, reject) => setTimeout(resolve, 1500));
let bbb = aaa;
console.log("in caller, resolve aaa : " bbb);
resolve(bbb);
});
});
}
async function main() {
console.log("main start ...");
await caller().then(function (aaa) {
new Promise((resolve, reject) => setTimeout(resolve, 5000));
console.log("in main, response :" aaa);
return new Promise((resolve) => {
new Promise((resolve, reject) => setTimeout(resolve, 6000));
console.log("in main, resolve result : " aaa);
resolve(aaa);
return;
});
});
}
console.log(" Top Level starts..");
main();
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
If you're a new learner, I challenge you to try rewriting your code not to use .then
entirely and then the other way around - not using async/await
at all.