需求很简单明了,实现超时报错,那这个怎么写呢?我们首先想到的可能是这样写,实现这个函数,传请求地址和超时时间,然后返回一个Promise,一旦 Promise 进入了 fulfilled 或 rejected 状态,它就是 settled(已定型)的,不会再改变状态。所以我们下面代码里的Promise只会返回一直状态,要么是成功,要么是失败(请求失败或者定时器记时结束返回失败)。
function createRequestWithTimeout(url, timeout) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject('Request timed out');
}, timeout);
fetch(url).then(resolve, reject)
})
}
createRequestWithTimeout('http://jsonplaceholder.typicode.com/posts', 500)
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
});
但是上面的代码有一个问题,那就是当接口超时,返回的是setTimeout里的reject的时候,fetch的请求最终还是会发出去,所以我们可以fetch的option配置一个signal来取消fetch的请求。
function createRequestWithTimeout(url, timeout) {
return new Promise((resolve, reject) => {
const control = new AbortController();
const signal = control.signal;
setTimeout(() => {
reject('Request timed out');
control.abort();
}, timeout);
fetch(url, {
signal: signal
}).then(resolve, reject)
})
}
createRequestWithTimeout('http://jsonplaceholder.typicode.com/posts', 10)
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
});