Search code examples
javascriptjqueryjquery-deferreddeferred

Implement Deferred object without using jquery


I want to implement basic Deferred object without using jQuery. Here i will be implementing only done and fail callbacks, with resolve and reject functions. and ofCourse associating promise method with this function.

i am doing the following implementation in pure js (Edited) :

function Deferred() {
    var d = {};
    d.resolve = function() {
        d.done(arguments);
    }
    d.reject = function() {
        d.fail(arguments);
    }
    d.promise = function() {
        var x = {};
        x.done = function(args) {
            return args;
        }
        x.fail = function(args) {
            return args;
        }
        return x;
    }
    return d;
}


var v;

var setVal = function() {
    var d = new Deferred();
    setTimeout(function() {
        v = 'a value';
        d.resolve(this);
    }, 5000);
    return d.promise();
};

setVal().done(function() {
    console.log('all done :' + v);
});

But the above gives the error : Object #<Object> has no method 'fail'

I know the returned object 'd' of Deferred() function does not have method done(). And if i returns d.promise from Deferred() this will not have resolve and reject functions.

Please point out what error i am making to achieve the simple objective of Deferred object.

Here is the fiddle i am doing : http://jsfiddle.net/SyEmK/14/


Solution

  • function Deferred(){
      this._done = [];
      this._fail = [];
    }
    Deferred.prototype = {
      execute: function(list, args){
        var i = list.length;
    
        // convert arguments to an array
        // so they can be sent to the
        // callbacks via the apply method
        args = Array.prototype.slice.call(args);
    
        while(i--) list[i].apply(null, args);
      },
      resolve: function(){
        this.execute(this._done, arguments);
      },
      reject: function(){
        this.execute(this._fail, arguments);
      }, 
      done: function(callback){
        this._done.push(callback);
      },
      fail: function(callback){
        this._fail.push(callback);
      }  
    }
    
    
    var v;
    
    var setVal = function() {
        var d = new Deferred();
        setTimeout(function() {
            v = 'a value';
            d.resolve(this);
        }, 5000);
        return d;
    };
    
    setVal().done(function() {
        console.log('all done :' + v);
    });