1.0.0 • Published 4 years ago

exfetch v1.0.0

Weekly downloads
369
License
MIT
Repository
github
Last release
4 years ago

exfetch

Build Status BrowserStack Status

Enhanced unfetch API.

Features:

Install

npm install exfetch --save

Usage

Custom abort implementation

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();
})();

"Abortable Fetch" approach

Using abort and isAborted export properties will throw error which instructs to use AbortController.abort() method and AbortSignal.aborted property respectively.

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;
		}
	}
})();

API

exfetch(url, options)

Returns: Object

See unfetch API documentation for arguments.

Returns API object with following properties:

request

Type: Function
Returns: Promise

Returns request Promise.

onEvent(eventName, handler)

Type: Function
Returns: Function

Wrapper around progress event.

Event nameOriginal handler
downloadxhr.onprogress
uploadxhr.upload.onprogress

Handler receives one argument which is original Event.

Returns function for unlistening event.

abort

Type: Function
Returns: undefined

Aborts request.

This has effect only with custom abort implementation. If you use this method with "abortable Fetch" approach, it will throw error telling you to use AbortController.abort() instead.

isAborted

Type: Function
Returns: boolean

Check if current request is aborted.

This has effect only with custom abort implementation. If you use this method with "abortable Fetch" approach, it will throw error telling you to use AbortSignal.aborted instead.

Questions

Why two different abort implementations?

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, 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 with ok set to false and status set to 0.

Browser support

Tested in IE11+ and all modern browsers, assuming Promise is available (polyfill).

If you want to use "abortable Fetch" approach, you also need to have AbortController available (polyfill).

Test

For automated tests, run npm run test:automated (append :watch for watcher support).

License

MIT © Ivan Nikolić