我有一个fetch-api
POST
请求:
fetch(url, {
method: 'POST',
body: formData,
credentials: 'include'
})
我想知道这是什么默认超时?我们如何将其设置为特定值,如3秒或无限秒?
答案 0 :(得分:65)
我非常喜欢gist使用Promise.race
的https://developer.apple.com/documentation/uikit/uitableviewdelegate/1614877-tableview方法fetchWithTimeout.js
configurations.all {
resolutionStrategy {
force 'com.android.support:design:27.0.2'
force 'com.android.support:support-v4:27.0.2'
force 'com.android.support:appcompat-v7:27.0.2'
}
}
main.js
android.enableAapt2=false
答案 1 :(得分:49)
它没有指定的默认值; the specification根本不讨论超时。
您可以为promises实现自己的超时包装:
// 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
答案 2 :(得分:27)
使用中止语法,您将能够:
const controller = new AbortController();
const signal = controller.signal;
const fetchPromise = fetch(url, {signal});
// 5 second timeout:
const timeoutId = setTimeout(() => controller.abort(), 5000);
fetchPromise.then(response => {
// completed request before timeout fired
// If you only wanted to timeout the request, not the response, add:
// clearTimeout(timeoutId);
})
请参阅MDN上的AbortController页面。
答案 3 :(得分:4)
fetch API中还没有超时支持。但它可以通过将其包含在承诺中来实现。
例如。
function fetchWrapper(url, options, timeout) {
return new Promise((resolve, reject) => {
fetch(url, options).then(resolve, reject);
if (timeout) {
const e = new Error("Connection timed out");
setTimeout(reject, timeout, e);
}
});
}
答案 4 :(得分:2)
编辑:获取请求仍将在后台运行,很可能会在您的控制台中记录错误。
确实,Promise.race方法更好。
请参阅此链接以获取参考Promise.race()
Race意味着所有Promises将同时运行,并且只要其中一个promises返回一个值,竞争就会停止。 因此,只会返回一个值。 如果提取超时,您也可以传递一个函数来调用。
fetchWithTimeout(url, {
method: 'POST',
body: formData,
credentials: 'include',
}, 5000, () => { /* do stuff here */ });
如果这引起了你的兴趣,可能的实施将是:
function fetchWithTimeout(url, options, delay, onTimeout) {
const timer = new Promise((resolve) => {
setTimeout(resolve, delay, {
timeout: true,
});
});
return Promise.race([
fetch(path, request),
timer
]).then(response) {
if (response.timeout) {
onTimeout();
}
return response;
}
}
答案 5 :(得分:2)
基于Endless出色的answer,我创建了一个有用的实用程序功能。
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
}
});
希望有帮助。
答案 6 :(得分:2)
如果您尚未在代码中配置超时,它将是浏览器的默认请求超时。
1)Firefox-90秒
在Firefox URL字段中输入about:config
。查找与键network.http.connection-timeout
2)Chrome-300秒
答案 7 :(得分:0)
您可以创建一个timeoutPromise包装器
class ExForm(forms.Form):
a = forms.CharField(max_length=100, initial='Some value')
b = forms.ChoiceField(choices=SOME_CHOICES)
c = forms.ChoiceField(choices=SOME_CHOICES)
然后您可以包装任何承诺
function timeoutPromise(timeout, err, promise) {
return new Promise(function(resolve,reject) {
promise.then(resolve,reject);
setTimeout(reject.bind(null,err), timeout);
});
}
它实际上不会取消基础连接,但可以使Promise超时。
Reference
答案 8 :(得分:0)
fetchTimeout (url,options,timeout=3000) {
return new Promise( (resolve, reject) => {
fetch(url, options)
.then(resolve,reject)
setTimeout(reject,timeout);
})
}
答案 9 :(得分:0)
答案 10 :(得分:0)
这是一个使用 NodeJS 的 SSCCE,它将在 1000 毫秒后超时:
const fetch = require('node-fetch');
const AbortController = require('abort-controller');
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 1000); // will time out after 1000ms
fetch('https://www.yourexample.com', {
signal: controller.signal,
method: 'POST',
body: formData,
credentials: 'include'
}
)
.then(response => response.json())
.then(json => console.log(json))
.catch(err => {
if(err.name === 'AbortError') {
console.log('Timed out');
}}
)
.finally( () => {
clearTimeout(timeout);
});