Skip to content

Instantly share code, notes, and snippets.

@acwhittam
Created September 6, 2021 16:15
Show Gist options
  • Save acwhittam/aa28bb027f5419938b840c0a71a679f8 to your computer and use it in GitHub Desktop.
Save acwhittam/aa28bb027f5419938b840c0a71a679f8 to your computer and use it in GitHub Desktop.
node fetch future
const R = require('ramda');
const {
Future, resolve, reject,
} = require('fluture');
const fetch = require('node-fetch');
const { Request } = fetch;
const AbortController = require('abort-controller');
const ConstructAbort = R.construct(AbortController);
const ConstructRequest = R.constructN(2, Request);
const construct = R.curryN(2, (options = {}, uri) => Future((rej, res) => {
const controller = ConstructAbort();
const { timeout = 5000 } = options;
const request = (R.compose(
ConstructRequest(uri),
R.mergeDeepRight({ signal: controller.signal }),
R.omit(['timeout']),
)(options));
const timer = setTimeout(() => { controller.abort(); }, timeout);
fetch(request)
.then(res)
.catch((error) => {
if (error.message === 'The user aborted a request.') {
rej(`Request timed out at ${timeout}ms`);
} else {
rej(error);
}
})
.finally(() => {
clearTimeout(timer);
});
return () => {
clearTimeout(timer);
controller.abort();
};
}));
module.exports = R.compose(
R.chain((response) => (response.ok ? resolve(response) : reject(response.statusText))),
construct,
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment