Ich habe eine Kette von Deferred in einem JavaScript Submit-Handler, die Reihe von AJAX-Aufrufe an eine API machen, bis das gewünschte Ergebnis zurückgegeben wird. Es hat gut funktioniert, aber ich habe ein paar Änderungen vorgenommen und jetzt kann ich nicht herausfinden, wo ich falsch gelaufen bin, denn der neue Code scheint eine gebrochene Kette von Versprechen zu haben.Deferred löst nicht auf
function createLinkAPIJob(type) {
//code to create a request
return $.ajax(request)
}
function getJobStatus(jobID) {
return $.ajax({
url: Urls['find_job'](jobID),
contentType: 'application/JSON',
method: 'GET'
})
}
// utility function to create a promise that is resolved after a delay
$.promiseDelay = function(t) {
return $.Deferred(function(def) {
setTimeout(def.resolve, t);
}).promise();
}
function waitForJobStatus(jobID, timeStarted) {
return $.Deferred(function(def) {
getJobStatus(jobID).then(function(data) {
console.log(data);
var isFinished = data['job']['finished'];
var jobStatus = 'incomplete';
var jobStatus = data['job']['job_status'];
if (isFinished === true) {
/***** HERE IS THE PROBLEM AREA *****/
console.log('resolving wait for job status');
def.resolve(jobStatus);
//also tried: return jobStatus;
} else {
return $.promiseDelay(1000).then(function() {
return waitForJobStatus(jobID, timeStarted);
});
}
});
}).promise();
}
function executeLinkAPIJob(type) {
return $.Deferred(function(def) {
createLinkAPIJob(type).then(function(response) {
var jobID = response['data']['job_id'];
var timeStarted = new Date().getTime()/1000;
console.log('waiting for job to finish');
waitForJobStatus(jobID, timeStarted).then(function(jobStatus) {
console.log('got job status, updating and resolving');
// A bunch of code here that doesn't matter for this issue...
def.resolve();
});
});
}).promise();
}
// I know this seems stupid in this example, but jobs is sometimes a longer array
jobs = [executeLinkAPIJob(type=type)]
.when.apply($, jobs).then(function() {
// do something
});
Die Konsole Ausgang davon
waiting for job to finish
Object {job: "{"error": "Job not found"}"}
Object {job: Object}
resolving wait for job status
was Sinn macht: Die erste Linie ist kurz vor waitForJobStatus
genannt zu werden, dann waitForJobStatus
versucht einmal und nicht einen Job zu finden, dann versucht es erneut nach 1 Sekunde und findet einen Job, so dass es die data
protokolliert, und schließlich, bevor ich auflösend, füge ich eine Konsolennachricht hinzu, um zu beweisen, dass wir es in den bedingten gemacht haben.
Aber dann die console.log('got job status, updating and resolving');
nie ausgelöst - die waitForJobStatus
nicht gelöst bekommen, ich denke, so dass die then
in createLinkAPIJob
nie ausgelöst
Vielen Dank für die Antwort und Beispielcode. Diese Antwort hat mir gestern nur halb Sinn gemacht (wie die meisten Antworten, die ich über Versprechungen in den letzten Monaten erhalten habe) - was mich genug frustrierte, dass ich JavaScript mit Promises gekauft und es gestern und heute Morgen gelesen habe, was längst überfällig war. Möge ich nie wieder mit einem Missverständnis über Versprechen kommen müssen! – fildred13