2013-08-07 18 views
6

Voglio implementare oggetto Deferred di base senza usare jQuery. Qui implementerò solo i callback eseguiti e non riusciti, con funzioni di risoluzione e rifiuto. e ofCourse che associano il metodo promise a questa funzione.Implementare oggetto differito senza usare jquery

sto facendo la seguente implementazione in js puri (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); 
}); 

Ma quanto sopra dà l'errore: Object #<Object> has no method 'fail'

So che l'oggetto 'd' tornato di Deferred() funzione non ha metodo fatto(). E se restituisco d.promise da Deferred() questo non avrà funzioni di risoluzione e rifiuto.

Si prega di indicare quale errore sto facendo per raggiungere l'obiettivo semplice dell'oggetto differito.

Ecco il violino sto facendo: http://jsfiddle.net/SyEmK/14/

+0

Se si crea un'istanza con 'new' allora si dovrebbe aggiungere i metodi per il' prototype'. Il costruttore restituisce un'istanza, anche se si restituisce d'. Potresti volere 'var d = Deferred()' – elclanrs

+0

Non hai un metodo chiamato done. Se guardi il tuo oggetto, hai risoluzione, rifiuto e promessa. setVal() restituisce un'istanza dell'oggetto con quei 3 metodi. – THEtheChad

+0

jQuery non è l'unica libreria per implementare le promesse. – JayC

risposta

18
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); 
}); 
+4

Se vuoi avvicinarti ancora di più al comportamento di jQuery, potresti voler aggiungere una funzione "promessa" che restituisce un oggetto con solo "done" e "fail" (in modo che la funzione chiamante non abbia accesso alla risoluzione/rifiuto). Inoltre, puoi restituire "this" da done/fail, per consentire il concatenamento. – lyosef

Problemi correlati