I've wrote a very simple implementation of Deferred / Promise pattern (inspired by jQuery's $.deferred
) for my tiny project (which does not use jQuery)
It can handle multiply onSuccess
an onFail
callbacks with result caching. Example in comments above the code.
/**
* defer() returns methods:
* resolve(data) - request is successfully resolved (returns nothing)
* reject(msg) - request if failed (returns nothing)
* promise() - returns promise function
*
* promise() returns methods:
* done(successfulCallback) - add on successful callback (returns nothing)
* fail(failCallback) - add on fail callback (returns nothing)
*
* Example:
*
* function someHeavyRequest(url) {
* var d = defer();
* doHeavyRequest(url,
* function (data) {
* // on success
* // ...do something
* d.resolve(data);
* },
* function (data) {
* // on fail
* // ...do something
* d.reject(data);
* });
* return d.promise();
* }
*
* var req = someHeavyRequest("http://some.url/of/request/");
*
* req.done(function (data) {
* console.log("We got it!");
* console.log(data);
* });
*
* req.done(function (data) {
* console.log("We got it again without new request!");
* console.log(data);
* });
*
* req.fail(function (data) {
* console.error("Something wrong");
* console.error(data);
* });
*
*/
function defer () {
var status = 0, // 0 = in progress / 1 = successful / -1 = fail
callbacks = { done: [], fail: [] },
args = { resolve: [], reject: [] },
execute = function (callbacks, args) {
var f;
while (callbacks.length) {
f = callbacks.shift();
if (f) f.apply(this, args);
}
};
return {
promise: function () {
return {
done: function (callback) {
callbacks.done.push(callback);
if (status === 1) {
execute(callbacks.done, args.resolve);
}
},
fail: function (callback) {
callbacks.fail.push(callback);
if (status === -1) {
execute(callbacks.fail,args.reject);
}
}
};
},
resolve: function () {
status = 1;
args.resolve = arguments;
execute(callbacks.done, args.resolve);
},
reject: function () {
status = -1;
args.reject = arguments;
execute(callbacks.fail, args.reject);
}
};
}
always
callback as well? – Johan Jun 13 '14 at 13:08always
is good idea. I've missed this becausealways
call not required in my project at now – ofstudio Jun 13 '14 at 16:13