2013-08-07 28 views
6

Chcę zaimplementować podstawowy obiekt Odroczony bez użycia jQuery. Tutaj będę realizować tylko wykonanych i niepowodzeniem wywołań zwrotnych, z funkcjami rozstrzygania i odrzucania. i ofCourse kojarzenia metody promise z tą funkcją.Implementacja Odroczony obiekt bez użycia jquery

robię następującą implementację w czystym JS (red):

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); 
}); 

Ale przede daje błąd: Object #<Object> has no method 'fail'

Znam zwrócony obiekt „D” Deferred() funkcji nie ma metoda done(). A jeśli zwrócę d.promise z Deferred(), to nie będzie miało funkcji rozstrzygania i odrzucania.

Proszę wskazać, jaki błąd popełniam, aby osiągnąć prosty cel obiektu Odroczony obiekt.

Oto skrzypce robię: http://jsfiddle.net/SyEmK/14/

+0

Jeśli utworzyć instancję z 'new' następnie należy dodać do metody' prototype'. Konstruktor zwraca instancję, nawet jeśli 'return d'. Możesz chcieć 'var d = Deferred()' – elclanrs

+0

Nie masz metody o nazwie done. Jeśli spojrzysz na swój obiekt, masz postanowienie, odrzucenie i obietnicę. setVal() zwraca instancję twojego obiektu tymi trzema metodami. – THEtheChad

+0

jQuery nie jest jedyną biblioteką, która realizuje obietnice. – JayC

Odpowiedz

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

Jeśli chcesz podejść jeszcze bliżej do zachowania jQuery, możesz chcieć dodać funkcję "obietnicy", która zwraca obiekt z tylko "done" i "fail" (tak, że funkcja wywołująca nie będzie miała dostępu do rozwiązywania/odrzucania). Ponadto - możesz zwrócić "to" z done/fail, aby umożliwić połączenie. – lyosef