Skip to content

Loading…

Returns a Promise object for cached and jqXHR from AJAX #6

Merged
merged 2 commits into from

3 participants

@craigspaeth

Let me know if I'm missing some subtlety with how jQuery Deferred and Promise work here.

Basically, I needed to get the chained callback methods (particularly .fail) from $.retrieveJSON. So here I'm returning the $.ajax response for ajax calls, and returning a new promise object for the cached calls.

(I also updated the repo's jQuery to the latest version)

Craig Spaeth added some commits
@wycats
Owner

Looks great! Thanks for this!

@wycats wycats merged commit b2139ff into wycats:master
@krisselden

How does the promise from this Deferred ever get resolved?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 13, 2011
  1. added tests & updated jQuery

    Craig Spaeth committed
  2. Returns the jqXHR for AJAX requests, and returns a jQuery.Defered().p…

    Craig Spaeth committed
    …romise for cached responses
Showing with 44 additions and 161 deletions.
  1. +10 −5 lib/jquery.offline.js
  2. +4 −154 public/jquery.js
  3. +30 −2 public/tests/test.offline.js
View
15 lib/jquery.offline.js
@@ -146,7 +146,7 @@
// store the result in the cache. This function will be
// deferred until later if the user is offline
function getData() {
- getJSON(url, data, function(json, status) {
+ return getJSON(url, data, function(json, status) {
if ( status == 'notmodified' ) {
// Just return if the response has a 304 status code
return false;
@@ -179,15 +179,20 @@
// If there is anything in the cache, call the callback
// right away, with the "cached" status string
if( text ) {
- var response = fn( $.parseJSON(text), "cached", { cachedAt: date } );
- if( response === false ) return false;
+ var obj = $.parseJSON(text);
+ var response = fn( obj, "cached", { cachedAt: date } );
+ if( response === false ) {
+ var dfd = $.Deferred().promise();
+ dfd.done = function(callback) { callback(obj) };
+ return dfd;
+ }
}
// If the user is online, make the Ajax request right away;
// otherwise, make it the most recent callback so it will
// get triggered when the user comes online
if (window.navigator.onLine) {
- getData();
+ return getData();
} else {
mostRecent = getData;
}
@@ -209,4 +214,4 @@
$.clearJSON = $.noop;
}
-})(jQuery);
+})(jQuery);
View
158 public/jquery.js
4 additions, 154 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
32 public/tests/test.offline.js
@@ -19,8 +19,8 @@ var baseTest = function( next, data, obj ) {
expectCached = obj.cached;
var successCount = expectCached ? (count + 1) : count;
-
- $.retrieveJSON("/ajax/app", data, function( json, text, flag ) {
+
+ var returned = $.retrieveJSON("/ajax/app", data, function( json, text, flag ) {
if(text == "success") {
if(obj.successFlag) {
ok( flag && flag.cachedAt, "a follow-up request should have the cache time" );
@@ -52,6 +52,12 @@ var baseTest = function( next, data, obj ) {
return obj.returnValue;
}
});
+ if(obj.returnsJQXHR) {
+ ok( returned.readyState > 0, 'retrieveJSON should return jqXHR' );
+ }
+ if(obj.returnsPromise) {
+ ok( returned.fail && returned.done, 'retrieveJSON should return a jQuery promise' );
+ }
}
if( $.support.localStorage ) {
@@ -63,6 +69,14 @@ if( $.support.localStorage ) {
});
});
+ asyncTest("the first time, it returns a jqXHR object from the AJAX call", function() {
+ $(document).dequeue().queue(function(next) {
+ setup(next);
+ }).queue(function(next) {
+ baseTest(next, {}, { start: true, cached: false, returnsJQXHR: true });
+ });
+ });
+
asyncTest("the second time, it gets additional data in the callback", function() {
$(document).dequeue().queue(function(next) {
setup(next);
@@ -96,6 +110,20 @@ if( $.support.localStorage ) {
baseTest(next, {}, { start: true, cached: true, returnValue: false });
});
});
+
+ asyncTest("if you return false, it will return a jQuery.Defered().promise object", function() {
+ // Use an expectation assertion here to confirm that the Ajax request
+ // doesn't run. If it did, we would have two more assertions.
+ expect(3);
+
+ $(document).dequeue().queue(function(next) {
+ setup(next);
+ }).queue(function(next) {
+ baseTest(next, {}, { cached: false });
+ }).queue(function(next) {
+ baseTest(next, {}, { start: true, cached: true, returnValue: false, returnsPromise: true });
+ });
+ });
asyncTest("different data gets cached differently", function() {
$(document).dequeue().queue(function(next) {
Something went wrong with that request. Please try again.