Enhanced unfetch API.
npm install exfetch[![Build Status][ci-img]][ci]
[![BrowserStack Status][browserstack-img]][browserstack]
Enhanced unfetch API.
Features:
- Progress listeners for download and upload
- Abortable request with custom implementation or
AbortController,
following [abortable Fetch][abortable-fetch] approach
``sh`
npm install exfetch --save
`js
import exfetch from 'exfetch';
(async () => {
const { request, abort, isAborted, onEvent } = exfetch('https://becky.com');
let downloaded = 0;
let uploaded = 0;
onEvent('download', (e) => {
if (e.lengthComputable) {
downloaded = e.loaded / e.total;
}
});
onEvent('upload', (e) => {
if (e.lengthComputable) {
uploaded = e.loaded / e.total;
}
});
setTimeout(() => {
// Will abort request after 2 seconds
abort();
}, 2000);
const response = await request();
if (isAborted()) {
// Request aborted!
return;
}
// Parse response as JSON
const data = await response.json();
})();
`
Using abort and isAborted export properties will throw error which instructsAbortController.abort()
to useAbortSignal.aborted
method and
property respectively.
`js
import exfetch from 'exfetch';
(async () => {
const controller = new AbortController();
const signal = controller.signal;
const { request, onEvent } = exfetch('https://becky.com', { signal });
let downloaded = 0;
let uploaded = 0;
onEvent('download', (e) => {
if (e.lengthComputable) {
downloaded = e.loaded / e.total;
}
});
onEvent('upload', (e) => {
if (e.lengthComputable) {
uploaded = e.loaded / e.total;
}
});
setTimeout(() => {
// Will abort request after 2 seconds
controller.abort();
}, 2000);
try {
const response = await request();
// Parse response as JSON
const data = await response.json();
} catch (error) {
if (error.name === 'AbortError') {
// Request aborted!
return;
}
}
})();
`
Returns: Object
See
unfetch API documentation
for arguments.
Returns API object with following properties:
#### request
Type: Function Promise
Returns:
Returns request Promise.
#### onEvent(eventName, handler)
Type: Function Function
Returns:
Wrapper around
progress event.
| Event name | Original handler |
| ---------- | ----------------------- |
| download | xhr.onprogress |upload
| | xhr.upload.onprogress |
Handler receives one argument which is original Event.
Returns function for unlistening event.
#### abort
Type: Function undefined
Returns:
Aborts request.
This has effect only with custom abort implementation. If you use this method
with ["abortable Fetch" approach][abortable-fetch], it will throw error telling
you to use AbortController.abort() instead.
#### isAborted
Type: Function boolean
Returns:
Check if current request is aborted.
This has effect only with custom abort implementation. If you use this method
with ["abortable Fetch" approach][abortable-fetch], it will throw error telling
you to use AbortSignal.aborted instead.
Original GitHub issue on aborting Fetch
is rather long and it culminated with generic AbortController approach not
connected only with Fetch, which is great for any kind of abortable operations.
But XHR already has simple solution for aborting requests and it would be shame
not to use that.
I wanted to support both approaches, but they have differences in how they are
resolved.
For ["abortable Fetch" approach][abortable-fetch], request Promise is rejected
with AbortError following standard implementation.
For custom abort approach, request Promise is resolved/fulfilled to response
object following
XHR abort operation sequence-method>)
with ok set to false and status set to 0.
Tested in IE11+ and all modern browsers, assuming Promise is available
(polyfill).
If you want to use ["abortable Fetch" approach][abortable-fetch], you also need
to have AbortController available
(polyfill).
For automated tests, run npm run test:automated (append :watch` for watcher
support).
MIT © Ivan Nikolić
[ci]: https://travis-ci.com/niksy/exfetch
[ci-img]: https://travis-ci.com/niksy/exfetch.svg?branch=master
[browserstack]: https://www.browserstack.com/
[browserstack-img]: https://www.browserstack.com/automate/badge.svg?badge_key=MTd2TTJxWHhNRHltNEpXUjVGVXd2QTg0NXhMeDNVdFNiZGJEZVAvZnlOQT0tLXdKc2Q1UEo5b2V1WWtnRWZvTU91MGc9PQ==--4e42ab7c6a6e0029de392caaaeca797b11b5f57d
[abortable-fetch]: https://developers.google.com/web/updates/2017/09/abortable-fetch