【问题标题】:Async/await - Combination of awaiting functions and non awaiting fucntions [duplicate]异步/等待 - 等待功能和非等待功能的组合[重复]
【发布时间】:2019-04-22 02:46:49
【问题描述】:

我想组合我需要等待的异步函数和不需要等待的函数。首先是代码...

async function doSomeStuff() {
  try {

    const data = await getDataFromDatabase()

    if(data.canDoStuff == "yes") {
       doAsynchronousStuffIDoNotNeedToAwait()
    }

    if(data.canDoSecondStuff == "yes") {
       doSecondAsynchronousStuffIDoNotNeedToAwait()
          .then(result => console.log("Done!");
    }

  } catch(err) {
    console.log(err)
  }
}

这是我的问题。如果我的doAsynchronousStuffIDoNotNeedToAwait() 抛出错误,它会触发 catch 函数吗?在第二个函数doSecondAsynchronousStuffIDoNotNeedToAwait() 中是否有更好的方法来处理结果?这段代码是否有一些缺点或者可以写得更好?

我希望问题清晰,代码简单易懂。如果没有,请发表评论,我将编辑我的问题。谢谢你:)

【问题讨论】:

  • 这不是建议的问题的重复。并非所有异步执行都建立在 Promise 之上。此外,对于提出这个问题的人来说,“触发和遗忘”是正在尝试的原则并不一定很明显 - 确定这将构成该问题答案的有用部分。

标签: javascript asynchronous promise async-await


【解决方案1】:

测试很容易:

awaiting 该值按预期工作:

function getDataFromDatabase(){
  return Promise.resolve({canDoStuff: "yes"})
}
function doAsynchronousStuffIDoNotNeedToAwait(){
  return Promise.reject("whoops")
}

async function doSomeStuff() {
  try {

    const data = await getDataFromDatabase()
    if(data.canDoStuff == "yes") {
       let d = await doAsynchronousStuffIDoNotNeedToAwait()
    }
    
  } catch(err) {
    console.log("caught error:", err)
  }
}

doSomeStuff()

如果没有await,您会收到未捕获的承诺拒绝错误(我认为您只能在查看控制台时看到 SO):

function getDataFromDatabase(){
  return Promise.resolve({canDoStuff: "yes"})
}
function doAsynchronousStuffIDoNotNeedToAwait(){
  return Promise.reject("whoops")
}

async function doSomeStuff() {
  try {

    const data = await getDataFromDatabase()
    if(data.canDoStuff == "yes") {
       doAsynchronousStuffIDoNotNeedToAwait()
    }
    
  } catch(err) {
    console.log("caught error", err)
  }
}

doSomeStuff()

这是有道理的,因为没有await,函数不会等待承诺解决,并且函数在有机会捕获被拒绝的承诺之前完成。

【讨论】:

  • 谢谢,我认为dotconnor的答案比较复杂,所以应该标记为答案。
  • 无需解释@Raold,很高兴你明白了。
【解决方案2】:

好吧,让我们试一试:

function getDataFromDatabase() {
  return new Promise((resolve) => {
    setTimeout(resolve, 250, {canDoStuff: 'yes', canDoSecondStuff: 'yes'});
  });
}
function doAsynchronousStuffIDoNotNeedToAwait() {
  return new Promise((resolve) => {
    setTimeout(resolve, 250);
  });
}
function doSecondAsynchronousStuffIDoNotNeedToAwait() {
  return new Promise((_, reject) => {
    setTimeout(reject, 250, 'error: doSecondAsynchronousStuffIDoNotNeedToAwait()');
  });
}
async function doSomeStuff() {
  try {

    const data = await getDataFromDatabase()
    if(data.canDoStuff == "yes") {
       doAsynchronousStuffIDoNotNeedToAwait()
    }

    if(data.canDoSecondStuff == "yes") {
       doSecondAsynchronousStuffIDoNotNeedToAwait()
          .then(result => console.log("Done!"));
    }

  } catch(err) {
    console.log(err)
  }
}
doSomeStuff();

正如您通过运行 sn-p 所看到的,错误不会被 try/catch 捕获,但您会得到一个全局的?错误,因为承诺不在 try catch 的“范围”内,异步等待 try/catch 捕获的唯一错误是抛出正常异常或等待的承诺被拒绝时。因此,您必须使用 catch 函数以旧方式处理异步错误。

function getDataFromDatabase() {
  return new Promise((resolve) => {
    setTimeout(resolve, 250, {canDoStuff: 'yes', canDoSecondStuff: 'yes'});
  });
}
function doAsynchronousStuffIDoNotNeedToAwait() {
  return new Promise((resolve) => {
    setTimeout(resolve, 250);
  });
}
function doSecondAsynchronousStuffIDoNotNeedToAwait() {
  return new Promise((_, reject) => {
    setTimeout(reject, 250, 'error: doSecondAsynchronousStuffIDoNotNeedToAwait()');
  });
}
async function doSomeStuff() {
  try {

    const data = await getDataFromDatabase()
    if(data.canDoStuff == "yes") {
       doAsynchronousStuffIDoNotNeedToAwait()
    }

    if(data.canDoSecondStuff == "yes") {
       doSecondAsynchronousStuffIDoNotNeedToAwait()
          .then(result => console.log("Done!")).catch((err) => console.log(err));
    }

  } catch(err) {
    console.log(err)
  }
}
doSomeStuff();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    • 2021-10-05
    • 2019-06-24
    • 1970-01-01
    相关资源
    最近更新 更多