
Why is my deferred object set to resolved instead of pending when calling a function that sets a new
Question:
I'm trying to get jQuery <a href="http://api.jquery.com/category/deferred-object/" rel="nofollow">deferred
</a> to work and am having some problems.
My system is using postMessage
to pass messages from and to sandboxed areas on a website. So when I request a service from a sandboxed area like this:
// on click of button
foo.requestService(options, function (response) {
$("#c").val(response); // set value of input button
}
Internally, I'm creating a new $.deferred
every time the button is clicked and the service is requested like so:
that.requestService = $.fn.requestService = function (options, callbackFunction) {
var deferred = new $.Deferred(),
callbackId = priv.generateUuid(),
callback = deferred;
// store callback to be retrieved by response handler
priv.trackCallback(callbackId, callback, callbackFunction);
// set type
if (options.type === undefined) {
options.type = "request/any";
}
// the callback function to be run, once a postMessage
// with the response is received
deferred.done(function(result, callbackFunction) {
if (callbackFunction) {
callbackFunction(result);
}
});
// trigger messaging
window.top.postMessage(options, window.location.href);
};
All works well, I can request my sandboxed service, run it, postMessage the result and retrieve the respective callback:
priv.returnResult = function (event) {
// here I get back the deferred (callback[0]) and callback function (callback[1])
var callback = priv.retrieveCallback(event.data.callback);
// problem = the callback stays resolved after the first function call
console.log(callback[0].state());
callback[0].resolve(event.data.result, callback[1]);
};
My problem is, although I'm creating a **new** $.Deferred
every time a service is requested, my deferred object only runs the first time and then is set to resolved
, preventing any further function calls to return a result.
I thought a new $.Deferred
would generate a new deferred every time a service is requested, which I can resolve to run my callback function.
<strong>Question</strong><br /> What do I need to do to get this to work? Is it not, that <strong>new</strong> creates a <strong>new</strong> object, which I can resolve? Do I have to somehow delete/remove the previous resolved.deferred object in order to make it work?
Thanks!
Answer1:Found a snippet extending jQuery deferred to handle "multiple deferred setters and resolvers":
$.extend({
StatelessDeferred: function () {
var doneList = $.Callbacks("memory"),
promise = {
done: doneList.add,
// Get a promise for this deferred
// If obj is provided, the promise aspect is added to the object
promise: function (obj) {
var i,
keys = ['done', 'promise'];
if (obj === undefined) {
obj = promise;
} else {
for (i = 0; i < keys.length; i += 1) {
obj[keys[i]] = promise[keys[i]];
}
}
return obj;
}
},
deferred = promise.promise({});
deferred.resolveWith = doneList.fireWith;
deferred.resolve = doneList.fire;
// All done!
return deferred;
}
});