try...catch不能异步捕获代码错误?

前言

或许这只是个基础知识,但或许你之前没有了解到这个,只是一贯的使用了try…catch。那就再学一下,在 JavaScript 中,try…catch 块确实是同步的,它用于捕获同步代码块中的异常。如果发生了异步操作中的错误,try…catch 无法捕获,因为它已经执行完毕,无法捕获异步代码中的异常。

看题说话

1.例题一
下面的代码有问题吗,能正常捕获到错误吗。当然是不能,上面已经解释过了。try…catch 无法捕获 setTimeout 中抛出的异常,因为 try 块在 setTimeout 回调执行之前已经完成。

try {
    setTimeout(() => {
        // 异步操作中的代码
        throw new Error('异步错误');
    }, 1000);
} catch (error) {
    console.error('捕获到错误:', error.message);
}

要处理异步代码中的错误,可以使用 Promise 的 catch 方法或异步函数的 try…catch:

const asyncFunction = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject(new Error('异步错误'));
        }, 1000);
    });
};

asyncFunction()
    .catch(error => {
        console.error('捕获到错误:', error.message);
    });

2.例题二
再看看另外一个例子,如下

try {
  Promise.resolve().then(() => {
    throw new Error('err')
  })
} catch (err) {
  console.log(err);
}

在这个例子中,Promise.resolve().then(() => { throw new Error('err') }) 中的 Promise 是异步的,所以 try...catch 无法捕获 Promise 中的错误。以下是几种改正的方式:

1. 使用 .catch() 处理 Promise 中的错误:

Promise.resolve()
  .then(() => {
    throw new Error('err');
  })
  .catch((err) => {
    console.log(err.message);
  });

2. 使用 async/await:

  try {
    await Promise.resolve().then(() => {
      throw new Error('err');
    });
  } catch (err) {
    console.log(err.message);
  }

拓展

写到这觉得应该拓展一下,这也是我在逛别的文章下看到的,那就总结一下。try…catch用于捕获异常,如果Promise 未进行 catch 捕获错误,在做监控时必要要捕获这些未处理的错误,怎么处理?除 Promise 外其他未被捕获的异常如何监听,那么资源加载错误如何监听并重新加载,常见场景 c 端 cdn 资源加载失败如何替补。

别说,平时也没做过这么多异常处理,一般就对接口请求做了一些统一的报错封装,单独调用接口时捕获错误并报错。对于资源问题我还真没处理过。研究一番,总结如下:

1. 全局错误监听器:

可以使用 window.onerror 来捕获全局未被捕获的异常:

window.onerror = function (message, source, lineno, colno, error) {
    console.error('全局错误:', message, source, lineno, colno, error);
    // 可以在这里上报错误或采取其他处理措施
    return true; // 阻止浏览器默认行为
};

2. Promise 错误监听:

使用 unhandledrejection 事件可以监听未捕获的 Promise 错误:

window.addEventListener('unhandledrejection', function (event) {
    console.error('未捕获的 Promise 错误:', event.reason);
    // 可以在这里上报错误或采取其他处理措施
    event.preventDefault(); // 阻止默认行为
});

3. 资源加载错误监听:

使用 window.addEventListener 监听 error 事件,可以捕获资源加载错误。例如,监听 元素的加载错误:

const imgElement = document.createElement('img');

imgElement.addEventListener('error', function (event) {
    console.error('资源加载错误:', event);
    // 可以在这里重新加载资源或采取其他处理措施
});

imgElement.src = 'path/to/your/image.jpg';
document.body.appendChild(imgElement);

4. CDN 资源加载失败替补:

如果 CDN 资源加载失败,尝试加载本地备用资源。可以通过以下方法替补:

const scriptElement = document.createElement('script');

scriptElement.src = 'https://cdn.example.com/your-script.js';
scriptElement.onerror = function () {
    console.error('CDN 资源加载失败,尝试替补本地资源。');
    // 加载本地备用资源
    const localScriptElement = document.createElement('script');
    localScriptElement.src = 'path/to/your-local-script.js';
    document.body.appendChild(localScriptElement);
};

document.body.appendChild(scriptElement);

平时看到些知识点喜欢总结一下,内容仅供参考,如有问题请不吝赐教。

你可能感兴趣的:(前端,try...catch)