一起使用 async await 和 .then

Posted

技术标签:

【中文标题】一起使用 async await 和 .then【英文标题】:using async await and .then together 【发布时间】: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 变量。 【参考方案1】:

我总是使用async/await.catch()而不是使用async/awaittry/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】:

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

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

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

【讨论】:

建议:添加代码围栏和语言标识符以突出显示代码并使其更具可读性。

以上是关于一起使用 async await 和 .then的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 async/await 编写 .then 函数,以便捕获来自 axios 的响应(在单独的文件和方法中,在 vue 中)

JS async和await关键字

async/await 在名为“then”的类方法中

Async / await vs then 哪个最适合性能?

Node.js - 使用 'async' 和 'await' 和 sequelize ORM

async await