Skip to content

Commit

Permalink
Add support for cancelling fetch requests with AbortController (#24419)
Browse files Browse the repository at this point in the history
Summary:
This adds https://github.com/mysticatea/abort-controller to polyfill [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController). This is used to cancel requests when using `fetch`.

This also updates `event-target-shim` to 5.0 to make sure we only have one version of this dependency. This updates required adding a polyfill for `console.assert` which is used by the new version. I made one based on https://github.com/gskinner/console-polyfill/blob/master/console.js#L74.

The polyfill is very small, especially since we already use `event-target-shim` so I think it makes sense to include in core.

Depends on #24418 so that the fetch polyfill supports the `signal` parameter.

Fixes #18115

[General] [Added] - Add support for cancelling fetch requests with AbortController
Pull Request resolved: #24419

Differential Revision: D14912858

Pulled By: cpojer

fbshipit-source-id: 8a6402910398db51e2f3e3262f07aabdf68fcf72
  • Loading branch information
janicduplessis authored and facebook-github-bot committed Apr 15, 2019
1 parent 5e44c08 commit 5e36b0c
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 6 deletions.
8 changes: 8 additions & 0 deletions Libraries/Core/setUpXHR.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,11 @@ polyfillGlobal('File', () => require('File'));
polyfillGlobal('FileReader', () => require('FileReader'));
polyfillGlobal('URL', () => require('URL').URL); // flowlint-line untyped-import:off
polyfillGlobal('URLSearchParams', () => require('URL').URLSearchParams); // flowlint-line untyped-import:off
polyfillGlobal(
'AbortController',
() => require('abort-controller/dist/abort-controller').AbortController, // flowlint-line untyped-import:off
);
polyfillGlobal(
'AbortSignal',
() => require('abort-controller/dist/abort-controller').AbortSignal, // flowlint-line untyped-import:off
);
8 changes: 7 additions & 1 deletion Libraries/polyfills/console.js
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,12 @@ function consoleGroupEndPolyfill() {
global.nativeLoggingHook(groupFormat(GROUP_CLOSE), LOG_LEVELS.info);
}

function consoleAssertPolyfill(expression, label) {
if (!expression) {
global.nativeLoggingHook('Assertion failed: ' + label, LOG_LEVELS.error);
}
}

if (global.nativeLoggingHook) {
const originalConsole = global.console;
// Preserve the original `console` as `originalConsole`
Expand All @@ -540,6 +546,7 @@ if (global.nativeLoggingHook) {
group: consoleGroupPolyfill,
groupEnd: consoleGroupEndPolyfill,
groupCollapsed: consoleGroupCollapsedPolyfill,
assert: consoleAssertPolyfill,
};

// If available, also call the original `console` method since that is
Expand All @@ -560,7 +567,6 @@ if (global.nativeLoggingHook) {
// we still should pass them to original console if they are
// supported by it.
[
'assert',
'clear',
'dir',
'dirxml',
Expand Down
7 changes: 7 additions & 0 deletions RNTester/js/XHRExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const XHRExampleFormData = require('./XHRExampleFormData');
const XHRExampleHeaders = require('./XHRExampleHeaders');
const XHRExampleFetch = require('./XHRExampleFetch');
const XHRExampleOnTimeOut = require('./XHRExampleOnTimeOut');
const XHRExampleAbortController = require('./XHRExampleAbortController');

exports.framework = 'React';
exports.title = 'XMLHttpRequest';
Expand Down Expand Up @@ -61,4 +62,10 @@ exports.examples = [
return <XHRExampleOnTimeOut />;
},
},
{
title: 'Abort Test',
render() {
return <XHRExampleAbortController />;
},
},
];
58 changes: 58 additions & 0 deletions RNTester/js/XHRExampleAbortController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/

'use strict';

const React = require('react');
const {Alert, Button, View} = require('react-native');

class XHRExampleAbortController extends React.Component<{}, {}> {
_timeout: any;

_submit(abortDelay) {
clearTimeout(this._timeout);
// eslint-disable-next-line no-undef
const abortController = new AbortController();
fetch('https://facebook.github.io/react-native/', {
signal: abortController.signal,
})
.then(res => res.text())
.then(res => Alert.alert(res))
.catch(err => Alert.alert(err.message));
this._timeout = setTimeout(() => {
abortController.abort();
}, abortDelay);
}

componentWillUnmount() {
clearTimeout(this._timeout);
}

render() {
return (
<View>
<Button
title="Abort before response"
onPress={() => {
this._submit(0);
}}
/>
<Button
title="Abort after response"
onPress={() => {
this._submit(5000);
}}
/>
</View>
);
}
}

module.exports = XHRExampleAbortController;
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,13 @@
"dependencies": {
"@babel/runtime": "^7.0.0",
"@react-native-community/cli": "^2.0.0",
"abort-controller": "^3.0.0",
"art": "^0.10.0",
"base64-js": "^1.1.2",
"connect": "^3.6.5",
"create-react-class": "^15.6.3",
"escape-string-regexp": "^1.0.5",
"event-target-shim": "^1.0.5",
"event-target-shim": "^5.0.1",
"fbjs": "^1.0.0",
"fbjs-scripts": "^1.1.0",
"invariant": "^2.2.4",
Expand Down
15 changes: 11 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,13 @@ abbrev@1:
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==

abort-controller@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
dependencies:
event-target-shim "^5.0.0"

absolute-path@^0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/absolute-path/-/absolute-path-0.0.0.tgz#a78762fbdadfb5297be99b15d35a785b2f095bf7"
Expand Down Expand Up @@ -2744,10 +2751,10 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=

event-target-shim@^1.0.5:
version "1.1.1"
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-1.1.1.tgz#a86e5ee6bdaa16054475da797ccddf0c55698491"
integrity sha1-qG5e5r2qFgVEddp5fM3fDFVphJE=
event-target-shim@^5.0.0, event-target-shim@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==

eventemitter3@^3.0.0:
version "3.1.0"
Expand Down

0 comments on commit 5e36b0c

Please sign in to comment.