2023-03-13 14:03:02 -04:00
|
|
|
const {scratchFetch} = require('scratch-storage/src/scratchFetch.js');
|
|
|
|
|
2019-11-14 08:10:26 -05:00
|
|
|
/**
|
|
|
|
* Fetch a remote resource like `fetch` does, but with a time limit.
|
|
|
|
* @param {Request|string} resource Remote resource to fetch.
|
|
|
|
* @param {?object} init An options object containing any custom settings that you want to apply to the request.
|
|
|
|
* @param {number} timeout The amount of time before the request is canceled, in milliseconds
|
|
|
|
* @returns {Promise<Response>} The response from the server.
|
|
|
|
*/
|
|
|
|
const fetchWithTimeout = (resource, init, timeout) => {
|
|
|
|
let timeoutID = null;
|
|
|
|
// Not supported in Safari <11
|
|
|
|
const controller = window.AbortController ? new window.AbortController() : null;
|
|
|
|
const signal = controller ? controller.signal : null;
|
|
|
|
// The fetch call races a timer.
|
|
|
|
return Promise.race([
|
2023-03-13 14:03:02 -04:00
|
|
|
scratchFetch(resource, Object.assign({signal}, init)).then(response => {
|
2019-11-14 08:10:26 -05:00
|
|
|
clearTimeout(timeoutID);
|
|
|
|
return response;
|
|
|
|
}),
|
|
|
|
new Promise((resolve, reject) => {
|
|
|
|
timeoutID = setTimeout(() => {
|
|
|
|
if (controller) controller.abort();
|
|
|
|
reject(new Error(`Fetch timed out after ${timeout} ms`));
|
|
|
|
}, timeout);
|
|
|
|
})
|
|
|
|
]);
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = fetchWithTimeout;
|