Skip to content

Commit 5e36b0c

Browse files
janicduplessisfacebook-github-bot
authored andcommitted
Add support for cancelling fetch requests with AbortController (#24419)
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
1 parent 5e44c08 commit 5e36b0c

File tree

6 files changed

+93
-6
lines changed

6 files changed

+93
-6
lines changed

Libraries/Core/setUpXHR.js

+8
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,11 @@ polyfillGlobal('File', () => require('File'));
3030
polyfillGlobal('FileReader', () => require('FileReader'));
3131
polyfillGlobal('URL', () => require('URL').URL); // flowlint-line untyped-import:off
3232
polyfillGlobal('URLSearchParams', () => require('URL').URLSearchParams); // flowlint-line untyped-import:off
33+
polyfillGlobal(
34+
'AbortController',
35+
() => require('abort-controller/dist/abort-controller').AbortController, // flowlint-line untyped-import:off
36+
);
37+
polyfillGlobal(
38+
'AbortSignal',
39+
() => require('abort-controller/dist/abort-controller').AbortSignal, // flowlint-line untyped-import:off
40+
);

Libraries/polyfills/console.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,12 @@ function consoleGroupEndPolyfill() {
519519
global.nativeLoggingHook(groupFormat(GROUP_CLOSE), LOG_LEVELS.info);
520520
}
521521

522+
function consoleAssertPolyfill(expression, label) {
523+
if (!expression) {
524+
global.nativeLoggingHook('Assertion failed: ' + label, LOG_LEVELS.error);
525+
}
526+
}
527+
522528
if (global.nativeLoggingHook) {
523529
const originalConsole = global.console;
524530
// Preserve the original `console` as `originalConsole`
@@ -540,6 +546,7 @@ if (global.nativeLoggingHook) {
540546
group: consoleGroupPolyfill,
541547
groupEnd: consoleGroupEndPolyfill,
542548
groupCollapsed: consoleGroupCollapsedPolyfill,
549+
assert: consoleAssertPolyfill,
543550
};
544551

545552
// If available, also call the original `console` method since that is
@@ -560,7 +567,6 @@ if (global.nativeLoggingHook) {
560567
// we still should pass them to original console if they are
561568
// supported by it.
562569
[
563-
'assert',
564570
'clear',
565571
'dir',
566572
'dirxml',

RNTester/js/XHRExample.js

+7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const XHRExampleFormData = require('./XHRExampleFormData');
1818
const XHRExampleHeaders = require('./XHRExampleHeaders');
1919
const XHRExampleFetch = require('./XHRExampleFetch');
2020
const XHRExampleOnTimeOut = require('./XHRExampleOnTimeOut');
21+
const XHRExampleAbortController = require('./XHRExampleAbortController');
2122

2223
exports.framework = 'React';
2324
exports.title = 'XMLHttpRequest';
@@ -61,4 +62,10 @@ exports.examples = [
6162
return <XHRExampleOnTimeOut />;
6263
},
6364
},
65+
{
66+
title: 'Abort Test',
67+
render() {
68+
return <XHRExampleAbortController />;
69+
},
70+
},
6471
];
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
* @flow
9+
*/
10+
11+
'use strict';
12+
13+
const React = require('react');
14+
const {Alert, Button, View} = require('react-native');
15+
16+
class XHRExampleAbortController extends React.Component<{}, {}> {
17+
_timeout: any;
18+
19+
_submit(abortDelay) {
20+
clearTimeout(this._timeout);
21+
// eslint-disable-next-line no-undef
22+
const abortController = new AbortController();
23+
fetch('https://facebook.github.io/react-native/', {
24+
signal: abortController.signal,
25+
})
26+
.then(res => res.text())
27+
.then(res => Alert.alert(res))
28+
.catch(err => Alert.alert(err.message));
29+
this._timeout = setTimeout(() => {
30+
abortController.abort();
31+
}, abortDelay);
32+
}
33+
34+
componentWillUnmount() {
35+
clearTimeout(this._timeout);
36+
}
37+
38+
render() {
39+
return (
40+
<View>
41+
<Button
42+
title="Abort before response"
43+
onPress={() => {
44+
this._submit(0);
45+
}}
46+
/>
47+
<Button
48+
title="Abort after response"
49+
onPress={() => {
50+
this._submit(5000);
51+
}}
52+
/>
53+
</View>
54+
);
55+
}
56+
}
57+
58+
module.exports = XHRExampleAbortController;

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,13 @@
8888
"dependencies": {
8989
"@babel/runtime": "^7.0.0",
9090
"@react-native-community/cli": "^2.0.0",
91+
"abort-controller": "^3.0.0",
9192
"art": "^0.10.0",
9293
"base64-js": "^1.1.2",
9394
"connect": "^3.6.5",
9495
"create-react-class": "^15.6.3",
9596
"escape-string-regexp": "^1.0.5",
96-
"event-target-shim": "^1.0.5",
97+
"event-target-shim": "^5.0.1",
9798
"fbjs": "^1.0.0",
9899
"fbjs-scripts": "^1.1.0",
99100
"invariant": "^2.2.4",

yarn.lock

+11-4
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,13 @@ abbrev@1:
11761176
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
11771177
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
11781178

1179+
abort-controller@^3.0.0:
1180+
version "3.0.0"
1181+
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
1182+
integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
1183+
dependencies:
1184+
event-target-shim "^5.0.0"
1185+
11791186
absolute-path@^0.0.0:
11801187
version "0.0.0"
11811188
resolved "https://registry.yarnpkg.com/absolute-path/-/absolute-path-0.0.0.tgz#a78762fbdadfb5297be99b15d35a785b2f095bf7"
@@ -2744,10 +2751,10 @@ etag@~1.8.1:
27442751
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
27452752
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
27462753

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

27522759
eventemitter3@^3.0.0:
27532760
version "3.1.0"

0 commit comments

Comments
 (0)