API 요청 시간 초과를 가져 오시겠습니까?
나는이 fetch-api
POST
요청을 :
fetch(url, {
method: 'POST',
body: formData,
credentials: 'include'
})
이에 대한 기본 제한 시간이 무엇인지 알고 싶습니다. 3 초 또는 무한 초와 같은 특정 값으로 어떻게 설정할 수 있습니까?
지정된 기본값이 없습니다. 사양 은 시간 초과에 대해 전혀 논의하지 않습니다.
일반적으로 프라 미스에 대한 자체 시간 초과 래퍼를 구현할 수 있습니다.
// 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
Promise.race를 사용 하는이 요점 의 깔끔한 접근 방식을 정말 좋아합니다.
fetchWithTimeout.js
export default function (url, options, timeout = 7000) {
return Promise.race([
fetch(url, options),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('timeout')), timeout)
)
]);
}
main.js
import fetch from './fetchWithTimeout'
// call as usual or with timeout as 3rd argument
fetch('http://google.com', options, 5000) // throw after max 5 seconds timeout error
.then((result) => {
// handle result
})
.catch((e) => {
// handle errors and timeout error
})
중단 구문을 사용하면 다음을 수행 할 수 있습니다.
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 페이지를 참조하십시오 .
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);
}
});
}
편집 : 가져 오기 요청은 여전히 백그라운드에서 실행되며 콘솔에 오류를 기록 할 가능성이 높습니다.
실제로 Promise.race 접근 방식이 더 좋습니다.
참조 Promise.race ()는 이 링크를 참조하십시오.
레이스는 모든 약속이 동시에 실행되고 약속 중 하나가 값을 반환하는 즉시 레이스가 중지됨을 의미합니다. 따라서 하나의 값만 반환 됩니다. 가져 오기 시간이 초과되면 호출 할 함수를 전달할 수도 있습니다.
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;
}
}
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(...)
It won't actually cancel an underlying connection but will allow you to timeout a promise.
Reference
fetchTimeout (url,options,timeout=3000) {
return new Promise( (resolve, reject) => {
fetch(url, options)
.then(resolve,reject)
setTimeout(reject,timeout);
})
}
Building on Endless' excellent answer, I created a helpful utility function.
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));
};
- If the timeout is reached before the resource is fetched then the fetch is aborted.
- If the resource is fetched before the timeout is reached then the timeout is cleared.
- If the input signal is aborted then the fetch is aborted and the timeout is cleared.
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
}
});
Hope that helps.
참고URL : https://stackoverflow.com/questions/46946380/fetch-api-request-timeout
'Nice programing' 카테고리의 다른 글
iOS 충돌 보고서 : atos가 예상대로 작동하지 않음 (0) | 2020.12.09 |
---|---|
Dart 코드에서 호스트 플랫폼을 어떻게 감지합니까? (0) | 2020.12.09 |
C에서 동적 다차원 배열을 어떻게 사용합니까? (0) | 2020.12.09 |
Django 파일 업로드 크기 제한 (0) | 2020.12.09 |
Java에서 System.out.println의 의미는 무엇입니까? (0) | 2020.12.09 |