2017-09-08 3 views
0

Ich versuche zu verwenden q verspricht, einige lang laufende Ajax-Anfragen und anschließende Datenverarbeitung zu behandeln. Ich habe einen Fall, in dem ich versuche, einige Versprechungen zu erstellen, die nacheinander ausgeführt werden sollten, aber sie scheinen zu lösen, bevor ich sie will, und ich bin mir nicht sicher warum.Mein Versprechen ist zu lösen, bevor ich denke, es sollte

Die Hauptreihe besteht darin, zuerst einige "Haupt" -Arbeitsschritte zu versuchen, die asynchron durchgeführt werden sollten, und dann einige "Folge" -Arbeitsschritte auszuführen, die ihrerseits mehrere asynchrone Anforderungen umfassen. Hier ist der Hauptkörper aus meiner Geige, die Demos das Problem:

var to_do = ["one", "two", "three", "four"]; 
var result = Q(); 
to_do.forEach(function (item) { 
    result = result 
    .then(dowork.bind(null, item)) 
    .fail(handleError) 
    .then(dofollowup.bind(null, item)); 
}); 

var dowork = function (value) { 
    var deferred = Q.defer(); 
    log("About to do main work for " + value); 
    setTimeout(function() { 
    if (value === 'two') { 
     // represent a possible error in this work, but we still need to do follow-up work 
     deferred.reject("An error occurred doing work for number two, but we should continue"); 
    } else { 
     log("Done main work for " + value); 
     deferred.resolve(value);  
    } 
    }, 1000); 
    return deferred.promise; 
} 

var dofollowup = function (value) { 
    log("Doing follow-up work for " + value); 
    var to_do = Q(); 
    for (var i=0; i<5; i++) { 
    to_do = to_do.then(function() { 
     var deferred = Q.defer(); 
     setTimeout(function() { 
     log("Doing delayed work for " + value); 
     deferred.resolve(); 
     }, 100); 
    }); 
    } 
    return to_do; 
} 

Mein unmittelbares Problem ist, dass die „main“ Arbeit für das nächste Element gestartet wird, bevor die „Follow-up“ Arbeit für ein Element fertig ist. Ich nehme an, dass ich mich mit den Versprechen nicht richtig auseinandersetze und sie versehentlich zu früh auflöse, aber ich sehe derzeit nicht, wie.

Ich habe eine Geige erstellt, die mein Problem simuliert. Darin sehe ich die Arbeit für das "Zwei" -Arbeitselement, die vor der Nachbereitung von "Eins" beginnt. Wie kann ich versichern, dass ich die Nachbearbeitung jedes Gegenstands beende, bevor ich mit der Hauptarbeit für den nächsten anfange?

https://jsfiddle.net/cfarmerga/cp323djx/1/

enter image description here

+0

Sie haben vergessen, Ihre aufgeschobene Versprechen in Ihrem dofollowup zurückgeben .. IOW: Sie erstellt eine zurückgestellt, aber nie zurückgegeben. – Keith

Antwort

2

Ihre dofollowup ändern scheint die latente zurückzukehren, dies zu beheben.

var dofollowup = function (value) { 

    log("Doing follow-up work for " + value); 

    var to_do = Q(); 
    for (var i=0; i<5; i++) { 
    to_do = to_do.then(function() { 
     var deferred = Q.defer(); 
     setTimeout(function() { 
     log("Doing delayed work for " + value); 
     deferred.resolve(); 
     }, 100); 
     return deferred.promise; //you forgot this.. 
    }); 
    } 
    return to_do; 

} 
+0

Ja, danke. Dies ist definitiv der Grund für das Problem in meiner Geige. Dies scheint jetzt offensichtlich zu sein, aber leider scheint es jetzt nicht meine Hauptanwendung nachzuahmen, die versagt. Vielleicht vergesse ich, das Versprechen von einer meiner angeketteten Funktionen wie diesem zurückzugeben. Zurück zum Graben! –

Verwandte Themen