我有一些代码基本上在 Javascript 中调用
fetch
。第三方服务有时需要很长时间才能返回响应,为了更加用户友好,我希望能够在 N 毫秒后发布消息或停止连接打开。
我最近看到这篇文章: 如果执行时间过长则跳过该函数。 JavaScript
但是运气不太好,在使用下面的代码时遇到了问题。我还希望有一种更现代的方法来完成这样的任务,也许使用
async/await
?
module.exports = (url, { ...options } = {}) => {
return fetch(url, {
...options
})
}
您可以组合使用 Promise.race 和 AbortController,这是一个示例:
function get(url, timeout) {
const controller = new AbortController();
return Promise.race([fetch(url, {
signal: controller.signal
}), new Promise(resolve => {
setTimeout(() => {
resolve("request was not fulfilled in time");
controller.abort();
}, timeout)
})]);
}
(async() => {
const result = await get("https://example.com", 1);
console.log(result);
})();
原生
Fetch
API 没有像 axios
那样内置超时功能,但您始终可以创建一个包装器函数来包装 fetch
调用来实现此功能。
这是一个例子:
const fetchWithTimeout = (timeout, fetchConfig) => {
const FETCH_TIMEOUT = timeout || 5000;
let didTimeOut = false;
return new Promise(function(resolve, reject) {
const timeout = setTimeout(function() {
didTimeOut = true;
reject(new Error('Request timed out'));
}, FETCH_TIMEOUT);
fetch('url', fetchConfig)
.then(function(response) {
// cleanup timeout
clearTimeout(timeout);
if(!didTimeOut) {
// fetch request was good
resolve(response);
}
})
.catch(function(err) {
// Rejection already happened with setTimeout
if(didTimeOut) return;
// Reject with error
reject(err);
});
})
.then(function() {
// Request success and no timeout
})
.catch(function(err) {
//error
});
}
我认为使用中止控制器的正确方法如下所示:https://developer.mozilla.org/en-US/docs/Web/API/AbortController以及setTimeout函数。