js - How to call an async function within a Promise .then()

给你一囗甜甜゛ 提交于 2021-02-06 22:57:43

问题


First, I have to mention that I already look through many questions in stackoverflow, but many doesn't answer my question. Not to mention many doesn't even have an answer.

How do I achieve the following, making sure functionB() executes after functionA() finishes?


Note: I do not want to convert my async functions to new Promise(resolve=>{...})
because I'll have to convert the someServiceThatMakesHTTPCall() as well, and any other async functions within the call stack, which is a big change.

  function functionThatCannotHaveAsyncKeyword() {
      functionA()
        .then(async function() {
            await functionB();
        })
        .then(function() {
            console.log('last');
        });
  }

  async function functionA() {
      console.log('first');
      await someServiceThatMakesHTTPCall();
  }

  async function functionB() {
      console.log('second');
      await someServiceThatMakesHTTPCall();
  }

回答1:


Your approach using await in an async then callback will work, but it's unnecessarily complex if all you want to do is call the async function and have its result propagate through the chain. But if you are doing other things and want the syntax benefit of async functions, that's fine. I'll come back to that in a moment.

async functions returns promises, so you just return the result of calling your function:

function functionThatCannotHaveAsyncKeyword() {
  functionA()
    .then(function() {
        return functionB(someArgument);
    })
    .then(function() {
        console.log('last');
    }); // <=== Note: You need a `catch` here, or this function needs
        // to return the promise chain to its caller so its caller can
        // handle errors
}

If you want to pass functionA's resolution value into functionB, you can do it even more directly:

functionA()
  .then(functionB)
  // ...

When you return a promise from a then callback, the promise created by the call to then is slaved to the promise you return.

Example:

const wait = (duration, ...args) => new Promise(resolve => {
  setTimeout(resolve, duration, ...args);
});

async function functionA() {
  await wait(500);
  return 42;
}

async function functionB() {
  await wait(200);
  return "answer";
}

functionB()
.then(result => {
  console.log(result); // "answer"
  return functionA();
})
.then(result => {
  console.log(result); // 42
})
.catch(error => {
  // ...handle error...
});

Coming back to your approach using an async then callback: That works too, and makes sense when you're doing more stuff:

const wait = (duration, ...args) => new Promise(resolve => {
  setTimeout(resolve, duration, ...args);
});

async function functionA() {
  await wait(500);
  return 42;
}

async function functionB() {
  await wait(200);
  return "answer";
}

functionB()
.then(async (result) => {
  console.log(result); // "answer"
  const v = await functionA();
  if (v < 60) {
    console.log("Waiting 400ms...");
    await wait(400);
    console.log("Done waiting");
  }
  console.log(v);      // 42
})
.catch(error => {
  // ...handle error...
});



回答2:


You can use promise inside the first method as

function functionThatCannotHaveAsyncKeyword() {
    return new Promise(async(resolve, reject)=> {
          await functionA();
          await functionB();
          console.log('last');
          resolve();    
      });
  }

  async function functionA() {
      console.log('first');
      await someServiceThatMakesHTTPCall();
  }

  async function functionB() {
      console.log('second');
      await someServiceThatMakesHTTPCall();
  }



回答3:


if someServiceThatMakesHTTPCall is async you can avoid all that by doing the following:

function functionThatCannotHaveAsyncKeyword() {
    functionA()
        .then(function() {
            return functionB()
        })
        .then(function() {
            console.log('last');
        });
  }

  function functionA() {
      console.log('first');
      return someServiceThatMakesHTTPCall();
  }

  function functionB() {
      console.log('second');
      return someServiceThatMakesHTTPCall();
  }


来源:https://stackoverflow.com/questions/54901478/js-how-to-call-an-async-function-within-a-promise-then

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!