【问题标题】:using async await and .then together一起使用 async await 和 .then
【发布时间】:2019-07-27 21:54:35
【问题描述】:

async/await和.then().catch()一起使用有什么坏处吗,比如:

async apiCall(params) {
    var results = await this.anotherCall()
      .then(results => {
        //do any results transformations
        return results;
      })
      .catch(error => {
        //handle any errors here
      });
    return results;
  }

【问题讨论】:

  • 我想anotherCall 是.then 打电话吗?
  • 抱歉,忘记了。现在添加它。
  • 不,没有害处。您只是使用await 将承诺链的最终值传递给result 变量。

标签: javascript node.js asynchronous promise async-await


【解决方案1】:

我总是使用async/await和.catch()而不是使用async/await和try/catch来紧凑地编写代码。

async function asyncTask() {
  throw new Error('network')
}
async function main() {
  const result = await asyncTask().catch(error => console.error(error));
  console.log('result:', result)
}

main();

如果你想在错误发生时获得一个回退值,你可以忽略错误并在.catch()方法中返回一个值

async function asyncTask() {
  throw new Error('network')
}
async function main() {
  const result = await asyncTask().catch(_ => 'fallback value');
  console.log('result:', result)
}

main();

【讨论】:

  • 我没有想到你的方式,但我真的很喜欢!我通常以相反的方式混合它们,使用带有 await 的 try / catch 语句并使用 .then 来执行额外的转换或对已解决的承诺进行任何操作。
  • 假设您在result = 行之后有更多代码。假设有一个错误。 result 然后是未定义的吗?
  • @JeffPadgett 是的,您可以从 .catch() 方法返回一个备用值
  • 您介意使用 .catch() 方法的后备更新您的答案吗?
  • @JeffPadgett 更新了答案。
【解决方案2】:

一个异步函数可以包含一个等待表达式来暂停 执行异步函数并等待传递的 Promise 解决,然后恢复异步函数的执行和 返回解析后的值。

从下面的示例中可以看出,您可以使用两种方法来处理等待结果和错误,关键字 await 使 JavaScript 等到该承诺解决并返回其结果(一个您从已解决的承诺中获得)。因此有没有害处(我不完全理解你在这里所说的危害)。

function returnpromise(val) {
  return new Promise((resolve, reject) => {
    if (val > 5) {
      resolve("resolved"); // fulfilled
    } else {
      reject("rejected"); // rejected
    }
  });
}

//This is how you handle errors in await
async function apicall() {
  try {
    console.log(await returnpromise(5))
  } catch (error) {
    console.log(error)
  }
}

async function apicall2() {
  let data = await returnpromise(2).catch((error) => {
    console.log(error)
  })
}

apicall2();
apicall();

更多参考请看-MDN DOCS

【讨论】:

    【解决方案3】:

    不想让死人复活,但想指出使用await 和then 链意味着:

    const x = await someAsyncFn().then(() => doSomeLogging());
    

    x 的值被赋值为.then 的返回值,这对我来说不是很直观。

    【讨论】:

      【解决方案4】:

      如果您使用 Async/await,则无需链接 .then(),只需将 resolve() 返回的结果存储在变量中(示例中为 response),但如果您想处理您遇到的错误尝试/捕获您的代码:

      async function f() {
      
        try {
          let response = await fetch('http://no-such-url');
        } catch(err) {
          alert(err); // TypeError: failed to fetch
        }
      }
      

      在你的承诺中使用:

      throw new Error("oops!");

      或者

      Promise.reject(new Error("Whoops!"));

      【讨论】:

      • 我一直在使用它,它比使用 .then + 另一个使整个事情难以辨认的匿名异步函数更好
      【解决方案5】:

      我认为混合使用 async/await + then 不是一个好主意。尤其是当你专注于 async func 的 res 时,混合使用会带来一些风险,会默默地扭曲你的 res。

      示例:

      const res = await fetchData().then(()=>{return "something else"}).catch((err)=>{});
      
      console.log(res); // not expected res data but something else
      

      所以,混用是危险的,顺便说一下,读码是有害的。

      【讨论】:

      • 建议:添加代码围栏和语言标识符以突出显示代码并使其更具可读性。
      猜你喜欢
      • 2021-03-21
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      • 2019-12-14
      • 2018-11-21
      • 2022-01-19
      • 2019-08-17
      • 2017-11-05
      相关资源
      最近更新 更多