异步/等待-等待功能和非等待功能的组合

时间:2018-11-19 17:25:02

标签: javascript asynchronous promise async-await

我想结合使用我需要等待的异步功能和不需要等待的功能。首先是代码...

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()中,有没有更好的方法来处理结果?该代码是否有缺点,或者可以编写更好的方法?

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

2 个答案:

答案 0 :(得分:1)

好吧,让我们尝试一下:

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();

通过运行代码段可以看到,try / catch不会捕获错误,但是您会得到全局错误?由于Promise错误不在try catch的“范围”内,因此,异步await try / catch捕获的唯一错误是当抛出正常异常或等待的Promise被拒绝时。因此,您必须使用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();

答案 1 :(得分:1)

测试起来很简单:

await值可按预期工作:

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的情况下,您会收到未捕获的承诺拒绝错误(我认为只有在控制台中才能看到该错误):

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,该函数不会等待承诺被解决,并且该函数会在有机会捕获被拒绝的承诺之前完成。