Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 5487bdb

Browse files
vojtajinaIgorMinar
authored andcommitted
feat($browser.xhr): add timeout option to abort request
Timeouted request responds internal status code -1, which should be normalized into 0 by $xhr.
1 parent 3ae3ccf commit 5487bdb

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

src/service/browser.js

+13-3
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,15 @@ function Browser(window, document, body, XHR, $log, $sniffer) {
9595
* <li><tt>X-Requested-With</tt>: <tt>XMLHttpRequest</tt></li>
9696
* </ul>
9797
*
98+
* @param {number=} timeout Timeout in ms, when the request will be aborted
9899
* @returns {XMLHttpRequest|undefined} Raw XMLHttpRequest object or undefined when JSONP method
99100
*
100101
* @description
101102
* Send ajax request
102103
*
103104
* TODO(vojta): change signature of this method to (method, url, data, headers, callback)
104105
*/
105-
self.xhr = function(method, url, post, callback, headers) {
106+
self.xhr = function(method, url, post, callback, headers, timeout) {
106107
outstandingRequestCount ++;
107108
if (lowercase(method) == 'jsonp') {
108109
var callbackId = ("angular_" + Math.random() + '_' + (idCounter++)).replace(/\d\./, '');
@@ -126,21 +127,30 @@ function Browser(window, document, body, XHR, $log, $sniffer) {
126127
if (value) xhr.setRequestHeader(key, value);
127128
});
128129

130+
var status;
129131
xhr.send(post || '');
130132

131133
// IE6, IE7 bug - does sync when serving from cache
132134
if (xhr.readyState == 4) {
133135
setTimeout(function() {
134-
completeOutstandingRequest(callback, fixStatus(xhr.status), xhr.responseText);
136+
completeOutstandingRequest(callback, fixStatus(status || xhr.status), xhr.responseText);
135137
}, 0);
136138
} else {
137139
xhr.onreadystatechange = function() {
138140
if (xhr.readyState == 4) {
139-
completeOutstandingRequest(callback, fixStatus(xhr.status), xhr.responseText);
141+
completeOutstandingRequest(callback, fixStatus(status || xhr.status),
142+
xhr.responseText);
140143
}
141144
};
142145
}
143146

147+
if (timeout > 0) {
148+
setTimeout(function() {
149+
status = -1;
150+
xhr.abort();
151+
}, timeout);
152+
}
153+
144154
return xhr;
145155
}
146156
};

test/service/browserSpecs.js

+17
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,23 @@ describe('browser', function() {
228228
expect(browser.xhr('GET', '/url', null, noop)).toBe(xhr);
229229
});
230230

231+
it('should abort request on timeout', function() {
232+
var callback = jasmine.createSpy('done').andCallFake(function(status, response) {
233+
expect(status).toBe(-1);
234+
});
235+
236+
browser.xhr('GET', '/url', null, callback, {}, 2000);
237+
xhr.abort = jasmine.createSpy('xhr.abort');
238+
239+
fakeWindow.setTimeout.flush();
240+
expect(xhr.abort).toHaveBeenCalledOnce();
241+
242+
xhr.status = 0;
243+
xhr.readyState = 4;
244+
xhr.onreadystatechange();
245+
expect(callback).toHaveBeenCalledOnce();
246+
});
247+
231248
it('should be async even if xhr.send() is sync', function() {
232249
// IE6, IE7 is sync when serving from cache
233250
var xhr;

0 commit comments

Comments
 (0)