Home > Net >  await promise function repeated but resolve/ return failed in 2nd
await promise function repeated but resolve/ return failed in 2nd

Time:11-07

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 awaited, but afterwards nothing happens with that. To fix that, return the promise chain instead of only awaiting 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.

  • Related