aboutsummaryrefslogtreecommitdiffstats
path: root/src/Browser.js
diff options
context:
space:
mode:
authorIgor Minar2010-12-04 23:49:26 -0800
committerIgor Minar2010-12-06 16:45:59 -0800
commit011fa39c2a0b5da843395b538fc4e52e5ade8287 (patch)
treeb5cc7ee72fb2fbcc76da2588822a21c2cedb614c /src/Browser.js
parent58d0e8945d772eddbfecbe6a645b2f1c4dd38bf2 (diff)
downloadangular.js-011fa39c2a0b5da843395b538fc4e52e5ade8287.tar.bz2
add $browser.defer and $defer service and fix async xhr cache issue
- Closes #152 ($resource().query() sometimes calls callback before returning, and it shouldn't) - add $browser.defer method - add $defer service - integrate $browser.defer with outstandingRequests counter in $browser - fix all old tests that relied on buggy behavior
Diffstat (limited to 'src/Browser.js')
-rw-r--r--src/Browser.js59
1 files changed, 45 insertions, 14 deletions
diff --git a/src/Browser.js b/src/Browser.js
index 197cf1f4..94807a8c 100644
--- a/src/Browser.js
+++ b/src/Browser.js
@@ -8,7 +8,7 @@ var XHR = window.XMLHttpRequest || function () {
throw new Error("This browser does not support XMLHttpRequest.");
};
-function Browser(location, document, head, XHR, $log) {
+function Browser(location, document, head, XHR, $log, setTimeout) {
var self = this;
self.isMock = false;
@@ -19,6 +19,28 @@ function Browser(location, document, head, XHR, $log) {
var outstandingRequestCount = 0;
var outstandingRequestCallbacks = [];
+
+ /**
+ * Executes the `fn` function (supports currying) and decrements the `outstandingRequestCallbacks`
+ * counter. If the counter reaches 0, all the `outstandingRequestCallbacks` are executed.
+ */
+ function completeOutstandingRequest(fn) {
+ try {
+ fn.apply(null, slice.call(arguments, 1));
+ } finally {
+ outstandingRequestCount--;
+ if (outstandingRequestCount === 0) {
+ while(outstandingRequestCallbacks.length) {
+ try {
+ outstandingRequestCallbacks.pop()();
+ } catch (e) {
+ $log.error(e);
+ }
+ }
+ }
+ }
+ }
+
/**
* @workInProgress
* @ngdoc method
@@ -58,19 +80,7 @@ function Browser(location, document, head, XHR, $log) {
outstandingRequestCount ++;
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
- try {
- callback(xhr.status || 200, xhr.responseText);
- } finally {
- outstandingRequestCount--;
- if (outstandingRequestCount === 0) {
- while(outstandingRequestCallbacks.length) {
- try {
- outstandingRequestCallbacks.pop()();
- } catch (e) {
- }
- }
- }
- }
+ completeOutstandingRequest(callback, xhr.status || 200, xhr.responseText);
}
};
xhr.send(post || '');
@@ -250,6 +260,27 @@ function Browser(location, document, head, XHR, $log) {
}
};
+
+ /**
+ * @workInProgress
+ * @ngdoc
+ * @name angular.service.$browser#defer
+ * @methodOf angular.service.$browser
+ *
+ * @description
+ * Executes a fn asynchroniously via `setTimeout(fn, 0)`.
+ *
+ * Unlike when calling `setTimeout` directly, in test this function is mocked and instead of using
+ * `setTimeout` in tests, the fns are queued in an array, which can be programaticaly flushed via
+ * `$browser.defer.flush()`.
+ *
+ * @param {function()} fn A function, who's execution should be defered.
+ */
+ self.defer = function(fn) {
+ outstandingRequestCount++;
+ setTimeout(function() { completeOutstandingRequest(fn); }, 0);
+ };
+
//////////////////////////////////////////////////////////////
// Misc API
//////////////////////////////////////////////////////////////