面试题答案
一键面试异步编程中异常处理的特殊之处
- Promise:
- 在Promise链中,如果某个Promise被拒绝(rejected),且没有被后续的
.catch()
处理,这个错误会一直沿着Promise链向上传播,直到被捕获。例如:
new Promise((resolve, reject) => { reject(new Error('Promise error')); })
- 在Promise链中,如果某个Promise被拒绝(rejected),且没有被后续的
.then(() => { console.log('This won't be executed'); }) .catch((error) => { console.error('Caught in Promise:', error.message); });
- 如果没有`.catch()`,错误就会成为未处理的Promise拒绝,在浏览器或Node.js环境中会触发相应的警告。
2. **async/await**:
- `async`函数内部如果抛出错误,该错误会被返回的Promise捕获。例如:
```javascript
async function asyncFunction() {
throw new Error('Async function error');
}
asyncFunction().catch((error) => {
console.error('Caught in async/await:', error.message);
});
- 当使用
await
时,如果等待的Promise被拒绝,await
会抛出这个错误,需要在try - catch
块中捕获。例如:
async function asyncFunctionWithAwait() {
try {
await new Promise((resolve, reject) => {
reject(new Error('Await error'));
});
} catch (error) {
console.error('Caught await error:', error.message);
}
}
asyncFunctionWithAwait();
实现通用错误边界
在JavaScript中,可以通过全局的window.onerror
(在浏览器环境)或process.on('uncaughtException')
(在Node.js环境)来捕获未处理的异常。但对于异步操作,更好的方式是利用async/await
结合全局的错误处理机制。
- 浏览器环境示例:
- 可以创建一个包装函数,在其中使用
try - catch
来捕获异步操作的错误。
function asyncErrorBoundary(func) { return async function (...args) { try { return await func.apply(this, args); } catch (error) { console.error('Uncaught async error:', error.message); // 可以在这里进行更复杂的处理,如上报错误到服务器 throw error; } }; } async function exampleAsyncFunction() { await new Promise((resolve, reject) => { setTimeout(() => { reject(new Error('Example async error')); }, 1000); }); } const safeExampleAsyncFunction = asyncErrorBoundary(exampleAsyncFunction); safeExampleAsyncFunction();
- 可以创建一个包装函数,在其中使用
- Node.js环境示例:
- 同样可以创建类似的包装函数,并且结合
process.on('uncaughtException')
进行全局处理。
function asyncErrorBoundary(func) { return async function (...args) { try { return await func.apply(this, args); } catch (error) { console.error('Uncaught async error:', error.message); // 可以在这里进行更复杂的处理,如上报错误到服务器 throw error; } }; } async function exampleAsyncFunction() { await new Promise((resolve, reject) => { setTimeout(() => { reject(new Error('Example async error')); }, 1000); }); } const safeExampleAsyncFunction = asyncErrorBoundary(exampleAsyncFunction); safeExampleAsyncFunction(); process.on('uncaughtException', (error) => { console.error('Global uncaught exception:', error.message); });
- 同样可以创建类似的包装函数,并且结合
通过上述方式,可以在异步编程中更好地处理异常,并实现通用的错误边界来确保应用程序的稳定性。