diff --git a/Libraries/Fetch/__tests__/fetch-test.js b/Libraries/Fetch/__tests__/fetch-test.js new file mode 100644 index 00000000000000..0881a6f27aa375 --- /dev/null +++ b/Libraries/Fetch/__tests__/fetch-test.js @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +'use strict'; + +jest.dontMock('fetch'); +const fetch = require('fetch').fetch; + +// Let fetch pick up a XMLHttpRequest mock from global scope +global.XMLHttpRequest = jest.fn(); + +describe('fetch', () => { + it('should only set XMLHttpRequest timeout if set in options', () => { + const url = 'http://foobar/'; + + fetch(url).then(() => {}, () => {}); + jest.runAllTicks(); + expect(XMLHttpRequest.mock.instances.length).toBe(1); + expect(XMLHttpRequest.mock.instances[0].timeout).toBeUndefined(); + + XMLHttpRequest.mockClear(); + + fetch(url, {timeout: 42}).then(() => {}, () => {}); + jest.runAllTicks(); + expect(XMLHttpRequest.mock.instances.length).toBe(1); + expect(XMLHttpRequest.mock.instances[0].timeout).toBe(42); + }); +}); diff --git a/Libraries/Fetch/fetch.js b/Libraries/Fetch/fetch.js index 7cb122a07f4cc2..a493cc9000f000 100644 --- a/Libraries/Fetch/fetch.js +++ b/Libraries/Fetch/fetch.js @@ -283,6 +283,7 @@ var self = {}; this.method = normalizeMethod(options.method || this.method || 'GET') this.mode = options.mode || this.mode || null this.referrer = null + this.timeout = options.timeout || null if ((this.method === 'GET' || this.method === 'HEAD') && body) { throw new TypeError('Body not allowed for GET or HEAD requests') @@ -376,6 +377,12 @@ var self = {}; var xhr = new XMLHttpRequest() + if (request.timeout) { + // Only set XMLHttpRequest timeout if set in options to + // avoid overriding the XMLHttpRequest default timeout + xhr.timeout = request.timeout + } + function responseURL() { if ('responseURL' in xhr) { return xhr.responseURL diff --git a/docs/Network.md b/docs/Network.md index 498a0df21cfec9..bc5de044dff592 100644 --- a/docs/Network.md +++ b/docs/Network.md @@ -35,6 +35,19 @@ fetch('https://mywebsite.com/endpoint/', { }) ``` +A non-standardized timeout option is available in the React Native implementation of the fetch API: + +```js +fetch('https://mywebsite.com/endpoint/', { + timeout: 30000 +}) +``` + +Notes: + - The timeout is specified in milliseconds. + - The default if unspecified is **no timeout**. + - The returned Promise is rejected if the request timeout. + #### Async `fetch` returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that can be processed in two ways: