简易版本
代码
function createRequestWithTimeout(timeout = 3000) {
return function (url, options) {
return new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => {
reject(new Error("Request timeout"));
}, timeout);
fetch(url, options)
.then((response) => {
clearTimeout(timeoutId);
return response.json();
})
.then((response) => {
clearTimeout(timeoutId);
return resolve(response);
})
.catch((error) => {
clearTimeout(timeoutId);
reject(error);
});
});
};
}
const request = createRequestWithTimeout();
function handle() {
request("api/abc/abc", { method: "GET" })
.then((res) => {
console.log(res);
})
.catch((error) => {
console.log(error);
});
}
解析
定义一个名为createRequestWithTimeout的函数,它返回一个新的函数,这个返回的函数用于发起一个带有超时机制的HTTP请求。 1、createRequestWithTimeout函数接收一个可选参数timeout,默认值为3000毫秒(3秒)。参数控制请求的超时时间。 2、返回的函数接收两个参数,url(请求的URL)和options(请求的选项,如请求方法、头部等)。个函数返回一个
Promise对象。 3、在返回的函数内部,首先使用setTimeout创建一个定时器,这个定时器会在timeout毫秒后触发。如果在timeout时间内请求没有完成,定时器会调用reject方法,传递一个错误对象,错误信息为"Request timeout"。 4、使用fetch函数发起HTTP请求。fetch函数接收url和options参数。 5、fetch返回的Promise被then方法处理。第一个then处理响应的body,将其转换为JSON格式。如果转换成功,它会调用resolve方法,传递解析后的数据。 6、如果在转换响应体为JSON时发生错误,或者在fetch请求过程中发生错误,catch方法会被调用,它会调用reject方法,传递错误信息。 7、在每个then和catch处理器中,都会调用clearTimeout来清除之前设置的超时定时器。这样做是为了确保在请求成功完成或失败时,不会触发超时错误。 8、handle函数调用request函数发起请求,并处理成功和失败的情况。成功时,它会打印响应数据;失败时,它会打印错误信息。 函数的目的是确保HTTP请求不会无限期地挂起,如果请求在指定的时间内没有完成,就会被中止,并且会通知调用者请求超时。这在处理可能需要较长时间的网络请求时非常有用,可以避免用户界面冻结或资源浪费。
升级版本
代码
function createRequestWithTimeout(timeout = 3000) {
return function (url, options) {
return new Promise((resolve, reject) => {
const abort = new AbortController();
options = options || {};
if (options.signal)
options.signal.addEventListener("abort", () => {
abort.abort();
});
options.signal = abort.signal;
setTimeout(() => {
reject(new Error("Request timeout"));
abort.abort();
}, timeout);
fetch(url, options)
.then((response) => {
return response.json();
})
.then((data) => {
return resolve(data);
})
.catch((error) => {
reject(error);
});
});
};
}
const request = createRequestWithTimeout();
function handle() {
request("api/abc/abc", { method: "GET" })
.then((res) => {
console.log(res);
})
.catch((error) => {
console.log(error);
});
}
解析
定义一个名为createRequestWithTimeout的函数,它返回一个异步函数,该函数可以发起一个带有超时机制的HTTP请求。 1、createRequestWithTimeout函数接受一个可选参数timeout,默认值为3000毫秒(3秒)。参数定义请求的超时时间。 2、createRequestWithTimeout返回一个函数,该函数接受两个参数,url(请求的URL)和options(请求的选项,如请求方法、头部等)。这个返回的函数返回一个Promise对象。 3、在返回的函数内部,首先创建一个
AbortController实例abort。AbortController是一个用于控制一个或多个Web请求的接口,它允许取消这些请求。 4、options参数被检查,如果它已经包含一个signal属性(即一个AbortSignal对象),则为该信号添加一个事件监听器。这个监听器会在signal被中止时调用abort.abort(),从而中止fetch请求。 5、options的signal属性被设置为abort实例的signal属性,这样就可以在超时发生时通过abort.abort()来中止请求。 6、使用setTimeout设置一个定时器,如果在timeout毫秒后请求还没有完成,setTimeout的回调函数会被调用,它会拒绝Promise并中止请求。 7、使用fetch函数发起HTTP请求。fetch函数接受url和options参数。 8、fetch返回的Promise被then方法处理。第一个then处理响应的body,将其转换为JSON格式。如果转换成功,它会调用resolve方法,传递解析后的数据。 9、如果在转换响应体为JSON时发生错误,或者在fetch请求过程中发生错误,catch方法会被调用,它会调用reject方法,传递错误信息。 10、handle函数调用request函数发起请求,并处理成功和失败的情况。成功时,它会打印响应数据;失败时,它会打印错误信息。 createRequestWithTimeout函数的目的是确保HTTP请求不会无限期地挂起。如果请求在指定的时间内没有完成,它会被中止,并且会通知调用者请求超时。这对于防止长时间挂起的请求导致的性能问题非常有用