下面是使用 Promise.race() 实现超时控制的代码示例,这个示例模拟了一个可能超时的异步操作(如网络请求),并在超时后触发错误处理:
// 1. 模拟一个实际的异步操作(例如接口请求)
function fetchData() {
return new Promise((resolve) => {
// 模拟网络请求延迟(这里设置为3秒,用于测试是否超时)
setTimeout(() => {
resolve("操作成功:获取到数据 { id: 1, name: '示例数据' }");
}, 3000);
});
}
// 2. 创建一个超时控制器
function createTimeoutController(timeoutMs, timeoutMsg) {
return new Promise((_, reject) => {
// 设定超时时间,超时后触发reject
setTimeout(() => {
reject(new Error(`超时:${timeoutMsg}(${timeoutMs}ms后)`));
}, timeoutMs);
});
}
// 3. 使用Promise.race()实现超时控制
function fetchDataWithTimeout(timeoutMs = 5000) {
// 竞速:实际操作 vs 超时控制器
return Promise.race([
fetchData(), // 实际要执行的异步操作
createTimeoutController(timeoutMs, "数据请求未在规定时间内完成") // 超时控制
]);
}
// 4. 使用带超时控制的异步操作
fetchDataWithTimeout(4000) // 设置超时时间为4秒
.then((result) => {
console.log("成功处理:", result);
// 输出:成功处理:操作成功:获取到数据 { id: 1, name: '示例数据' }
// (因为3秒的请求耗时 < 4秒超时时间)
})
.catch((error) => {
console.error("错误处理:", error.message);
// 如果将超时时间设为2000ms,会输出:
// 错误处理:超时:数据请求未在规定时间内完成(2000ms后)
});
代码解析:
fetchData():模拟一个可能耗时的异步操作(如API请求),这里用setTimeout模拟3秒的网络延迟。createTimeoutController():创建一个超时控制器,接收超时时间(毫秒)和超时提示信息,在指定时间后会reject一个错误。fetchDataWithTimeout():核心函数,通过Promise.race()让实际异步操作和超时控制器“竞速”:- 如果异步操作在超时前完成,就返回操作结果
- 如果超时时间先到,就触发超时错误
使用示例:设置超时时间为4秒(长于3秒的操作耗时),会正常返回结果;如果将超时时间设为2秒(短于操作耗时),则会触发超时错误。
这种模式广泛应用于需要控制异步操作最大耗时的场景,如网络请求、文件读取等,避免程序无限期等待。