我有一个fetch-api POST请求:
fetch(url, {
method: 'POST',
body: formData,
credentials: 'include'
})
我想知道这个的默认超时时间是多少?我们如何将它设置为特定的值,比如3秒或不定秒?
我有一个fetch-api POST请求:
fetch(url, {
method: 'POST',
body: formData,
credentials: 'include'
})
我想知道这个的默认超时时间是多少?我们如何将它设置为特定的值,比如3秒或不定秒?
当前回答
编辑1
正如注释中所指出的,原始答案中的代码即使在承诺被解析/拒绝之后也会继续运行计时器。
下面的代码修复了这个问题。
function timeout(ms, promise) {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
reject(new Error('TIMEOUT'))
}, ms)
promise
.then(value => {
clearTimeout(timer)
resolve(value)
})
.catch(reason => {
clearTimeout(timer)
reject(reason)
})
})
}
原来的答案
它没有指定的默认值;该规范根本没有讨论超时。
你可以为promise实现自己的超时包装器:
// Rough implementation. Untested.
function timeout(ms, promise) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
reject(new Error("timeout"))
}, ms)
promise.then(resolve, reject)
})
}
timeout(1000, fetch('/hello')).then(function(response) {
// process response
}).catch(function(error) {
// might be a timeout error
})
如https://github.com/github/fetch/issues/175所述 评论来源:https://github.com/mislav
其他回答
如果您没有在代码中配置超时,它将是浏览器的默认请求超时。
1) Firefox - 90秒
在Firefox URL字段中输入about:config。找到key network.http.connection-timeout对应的值
2) Chrome - 300秒
源
基于无尽的回答,我创造了一个有用的效用函数。
const fetchTimeout = (url, ms, { signal, ...options } = {}) => {
const controller = new AbortController();
const promise = fetch(url, { signal: controller.signal, ...options });
if (signal) signal.addEventListener("abort", () => controller.abort());
const timeout = setTimeout(() => controller.abort(), ms);
return promise.finally(() => clearTimeout(timeout));
};
如果在获取资源之前达到了超时,则会中止获取。 如果在超时之前获取资源,则超时将被清除。 如果输入信号被中止,那么取回将被中止,超时时间将被清除。
const controller = new AbortController();
document.querySelector("button.cancel").addEventListener("click", () => controller.abort());
fetchTimeout("example.json", 5000, { signal: controller.signal })
.then(response => response.json())
.then(console.log)
.catch(error => {
if (error.name === "AbortError") {
// fetch aborted either due to timeout or due to user clicking the cancel button
} else {
// network error or json parsing error
}
});
fetchTimeout (url,options,timeout=3000) {
return new Promise( (resolve, reject) => {
fetch(url, options)
.then(resolve,reject)
setTimeout(reject,timeout);
})
}
您可以创建一个timeoutPromise包装器
function timeoutPromise(timeout, err, promise) {
return new Promise(function(resolve,reject) {
promise.then(resolve,reject);
setTimeout(reject.bind(null,err), timeout);
});
}
然后可以包装任何承诺
timeoutPromise(100, new Error('Timed Out!'), fetch(...))
.then(...)
.catch(...)
它实际上不会取消底层连接,但允许您超时承诺。 参考
使用AbortController和setTimeout;
const abortController = new AbortController();
let timer: number | null = null;
fetch('/get', {
signal: abortController.signal, // Content to abortController
})
.then(res => {
// response success
console.log(res);
if (timer) {
clearTimeout(timer); // clear timer
}
})
.catch(err => {
if (err instanceof DOMException && err.name === 'AbortError') {
// will return a DOMException
return;
}
// other errors
});
timer = setTimeout(() => {
abortController.abort();
}, 1000 * 10); // Abort request in 10s.
这是@fatcherjs/middleware-aborter中的一个片段。
通过使用fatcher,可以很容易地中止取回请求。
import { aborter } from '@fatcherjs/middleware-aborter';
import { fatcher, isAbortError } from 'fatcher';
fatcher({
url: '/bar/foo',
middlewares: [
aborter({
timeout: 10 * 1000, // 10s
onAbort: () => {
console.log('Request is Aborted.');
},
}),
],
})
.then(res => {
// Request success in 10s
console.log(res);
})
.catch(err => {
if (isAbortError(err)) {
//Run error when request aborted.
console.error(err);
}
// Other errors.
});