不使用 try-catch 在 async-await 中捕获错误和数据

2025-06-07

不使用 try-catch 在 async-await 中捕获错误和数据

席卷 JavaScript 社区的一件事就是 async-await 的推出。它简洁易用,比 Promises 的 then-catch 代码看起来好很多,也比回调地狱更易读、更易于调试。但 try-catch 的使用却让我很困扰。起初我以为这没什么问题,但命运弄人,我在处理链式 API 调用时,问题出现了:每个 API 调用都需要打印特定的错误消息。我很快意识到,我正在创造一个 try-catch 地狱。

让我们考虑一下这个 Promise,它根据参数在 2 秒后解析或拒绝rejectPromise

// api.js

const fetchData = async (duration, rejectPromise) => (
  new Promise((resolve, reject) => {
    setTimeout(() => {
      if (rejectPromise) {
        reject({
          error: 'Error Encountered',
          status: 'error'
        })
      }
      resolve({
        version: 1,
        hello: 'world',
      });
    }, duration);
  })
);

module.exports = {
  fetchData,
};
Enter fullscreen mode Exit fullscreen mode

所以我对 async-await 的典型用法是这样的。

const { fetchData } = require('./api');

const callApi = async () => {
  try {
    const value = await fetchData(2000, false);
    console.info(value);
  } catch (error) {
    console.error(error);
  }
}

callApi();

/* 
 OUTPUT: 
 { version: 1, hello: 'world' } (rejectPromise=false)

 { error: 'Error Encountered', status: 'error' } (rejectPromise=true)

 */
Enter fullscreen mode Exit fullscreen mode

正如您所看到的,当rejectPromise参数为时, falseawait 解析为,{ version: 1, hello: 'world' }而当参数为时,true它拒绝承诺并调用 catch,错误为{ error: 'Error Encountered', status: 'error' }

这就是 async-await 的典型实现。现在,我们将利用 promise 函数 then-catch 来简化这个过程。让我们编写一个包装器来实现这一点。

// wrapper.js

const wrapper = promise => (
  promise
    .then(data => ({ data, error: null }))
    .catch(error => ({ error, data: null }))
);

module.exports = wrapper;
Enter fullscreen mode Exit fullscreen mode

我们可以看到,包装器接受一个 Promise 作为输入,并通过 then-catch 返回已解析/已拒绝的值。那么,让我们修改一下我们之前在 try-catch 中编写的代码,以便使用这个包装器。

const { fetchData } = require('./api');
const wrapper = require('./wrapper');

const callApi = async () => {
  const { error, data } = await wrapper(fetchData(2000, false));
  if (!error) {
    console.info(data);
    return;
  }
  console.error(error);
}

callApi();

/* 
 OUTPUT: 
 { version: 1, hello: 'world' } (rejectPromise=false)

 { error: 'Error Encountered', status: 'error' } (rejectPromise=true)

 */
Enter fullscreen mode Exit fullscreen mode

瞧,输出相同,但这种方式更容易理解代码。

文章来源:https://dev.to/sadarshannaiynar/capture-error-and-data-in-async-await-without-try-catch-1no2
PREV
使用 MERN Stack 的社交媒体应用程序创建 Node.js Rest API 设计 React 组件创建 MERN Stack 社交媒体应用程序使用 Socket.io 的实时聊天应用程序
NEXT
排序算法可视化工具