2015-10-03 3 views
6

Ich habe eine Folge von Funktionen, die ausgeführt werden müssen. Sie alle werden nacheinander ausgeführt, mit Ausnahme des letzten. d1 führt aus, d2 führt aus, d3 führt aus, dann wird der Code innerhalb der done-Funktion vor der Auflösung von d4 ausgeführt. Kann nicht herausfinden warum. Jede Hilfe wäre willkommen.Jquery Defered Nicht zuletzt.

$(document).ready(function() { 
    var d1 = functiond1(); 
    var d2 = functiond2(); 
    var d3 = functiond3(); 
    var d4 = functiond4(); 

    d1.then(d2).then(d3).then(d4).done(function() { 

    //Code here does not wait for d4 to end before executing 
    //HELP! 

    }); 
}); 

function functiond1() { 
    var dfd = $.Deferred(); 

    //Do stuff here 
    //Works in sequence 

    dfd.resolve(); 
    return dfd.promise(); 
} 


function functiond2() { 

    var dfd = $.Deferred(); 
    params = jQuery.param({ 
     'parm1': 1, 
     'parm2': 2, 
     'parm3': 3 
    }); 


    jQuery.getJSON($.webMethoJSONGet1, params).done(function(data) { 

     //Do stuff here 
     //Works in sequence 

     dfd.resolve(); 

    }); 

    return dfd.promise(); 
} 

function functiond3() { 
    var dfd = $.Deferred(); 

    //Do stuff here 
    //Works in sequence 

    dfd.resolve(); 
    return dfd.promise(); 
} 

function functiond4() { 

    var dfd = $.Deferred(); 

    params = jQuery.param({ 
     'parm1': 1, 
     'parm2': 2, 
     'parm3': 3 
    }); 

    jQuery.getJSON($.webMethoJSONGet2, params).done(function(data) { 

     //Do stuff here 
     //does not work in sequence 

     dfd.resolve(); 

    }); 

    return dfd.promise(); 
} 
+1

Wenn um Hilfe zu bitten, einrücken bitte Ihren Code readably . Ich habe den Code durch jsbeautifier für Sie ausgeführt. –

+0

Toller Tipp. Erledigt wie gewünscht. Irgendwelche Tipps in Bezug auf den Code? –

+1

Warum haben Sie bisher den gesamten Code eingerückt? Ich habe es bereits für dich festgelegt, jetzt ist mehr davon rechts davon als nötig. Ich habe es neu festgelegt. –

Antwort

-2

Ich war an einem Projekt mit dem gleichen Problem konfrontiert, diese Lösung mit einer Reihe gut funktioniert:

$(document).ready(function() { 
 
    var pr = []; 
 
    var d1 = functiond1(); 
 
    var d2 = functiond2(); 
 
    var d3 = functiond3(); 
 
    var d4 = functiond4(); 
 

 
    function functiond1() { 
 
     var dfd = $.Deferred(); 
 
     pr.push(dfd); 
 

 
     setTimeout(function(){ 
 
      $('body').append('1 resolved <br>'); 
 
      dfd.resolve(); 
 
     }, 2000); 
 
    } 
 

 

 
    function functiond2() { 
 
     var dfd = $.Deferred(); 
 
     pr.push(dfd); 
 

 
     params = jQuery.param({ 
 
      'parm1': 1, 
 
      'parm2': 2, 
 
      'parm3': 3 
 
     }); 
 

 
     setTimeout(function(){ 
 
      $('body').append('2 resolved <br>');    
 
      dfd.resolve(); 
 
     }, 3000); 
 
    } 
 

 
    function functiond3() { 
 
     var dfd = $.Deferred(); 
 
     pr.push(dfd); 
 

 
     setTimeout(function(){ 
 
      $('body').append('3 resolved <br>'); 
 
      dfd.resolve(); 
 
     }, 1000); 
 
    } 
 

 
    function functiond4() { 
 
     var dfd = $.Deferred(); 
 
     pr.push(dfd); 
 

 
     params = jQuery.param({ 
 
      'parm1': 1, 
 
      'parm2': 2, 
 
      'parm3': 3 
 
     }); 
 

 
     setTimeout(function(){ 
 
      $('body').append('4 resolved <br>'); 
 
      dfd.resolve(); 
 
     }, 50); 
 
    } 
 

 
    $.when.apply($, pr).then(function() { 
 
     // do something 
 
     $('body').append('proceed with code execution'); 
 
    }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

+0

Danke für die Antwort. Ich bestätige. –

+0

Gern geschehen, bitte teilen Sie Ihren Code für den Fall, dass es nicht funktioniert. – Spidi

+0

NB: Dieser Code wird _all vier_ Funktionen gleichzeitig ausführen lassen, ihre Async-Aufgaben parallel ausführen und nur auflösen, wenn alle fertig sind. – Alnitak

1

Es ist schwer zu sagen, was Sie versuchen, mit denen zu tun Versprechen. Sie rufen zuerst alle 4 Funktionen auf, und dann versuchen Sie, sie mit einer Reihe von then Callbacks zu verketten. Wenn Sie Kette sie sequentiell wollen zusammen sollte es so aussehen:

functiond1() 
.then(functiond2) 
.then(functiond3) 
.then(functiond4) 
.done(function() { /* blah */ }); 

Wenn Sie nur ein Ergebnis wollen, nachdem alle abgeschlossen haben Sie $.when

$.when(functiond1(), functiond2(), functiond3(), functiond4()) 
.then(function(resultd1, resultd2, resultd3, resultd4) { /* blah */ }); 

Auf einer anderen Anmerkung verwenden, können Sie in Ihren Funktionen Erstellen Sie Versprechen, die innerhalb der done Rückruf eines anderen Versprechens gelöst werden, die unnötig ist. Die $.getJSON.done() Anrufe geben ein Versprechen selbst zurück, so dass ein zusätzliches Versprechen nicht benötigt wird. Geben Sie einfach das Versprechen zurück, das von done() zurückgegeben wird.

Es tut mir leid, ich habe nicht viel mit jQuery verschobenen Objekten durcheinander gebracht, aber sie scheinen den Standardversprechen ähnlich zu sein.

+1

nein, das ist falsch - Sie müssen einen Funktionsverweis auf '.then' übergeben, nicht das Ergebnis des sofortigen Aufrufs dieser Funktion – Alnitak

+0

@Alnitak Ich reparierte es, um den Aufruf der Funktion innerhalb' then' zu verzögern. Vielen Dank. –

+0

Ja, ich rufe nach Funktionen, die jeweils eine Zusage zurückgeben, die nicht mit der nächsten fortgesetzt werden sollte, bis die vorherige gelöst ist, aber die letzte wartet nicht bis zur Auflösung. –

0

Um die Funktionen in der Reihenfolge auszuführen, müssen Sie Referenzen auf die Funktionen innerhalb der .then Kette und nicht die Ergebnisse des Aufrufs, diese Funktionen zu übergeben.

z.B.

var d1 = functiond1; // NB: no() 
... 

d1.then(d2).then(d3).then(d4).done(...);  
functiond1().then(functiond2).then(functiond3).then(functiond4).done(...) 

Die ultimative Ursache des Problems ist, dass d4 sofort Berufung auf seinen aufgelösten Versprechen dazu führen, Pass-Thru zu .done sofort, unabhängig vom Zustand des früheren Teils der .then Kette.

sollten Sie auch nicht Ihre JSON Funktionen mit zusätzlichen Versprechen wickeln, da $.getJSON bereits ein Versprechen zurückgibt, die abgelehnt werden, wenn die AJAX-Abfrage fehlschlägt:

function functiond4() { 
    ... 
    return $.getJSON(...); 
} 
+0

Danke für die Antwort. Achten Sie nicht auf die Funktionsnamen. Ich habe sie von den Originalen geändert, bevor ich die Frage gestellt habe, um die Funktionsreihenfolge hervorzuheben. Vertraue darauf, dass das nicht die Namen sind, die ich benutze. –