2016-06-20 2 views
0

Ich weiß, dass dies ein Missverständnis von mir ist und ich versuche zu lernen, was ich falsch mache, und ich könnte wirklich etwas Hilfe bitte verwenden.jQuery .done nicht wie erwartet

Ich habe eine Ajax-Anfrage, die erfolgreich ist und die Rückgabe von Daten gut. Die Api gibt einen Fehlercode zurück, und dann versuche ich eine Antwort basierend auf dem Code, den ich erhalten habe, zurückzugeben, außer dass die Funktion nur das zurückgibt, was der Ajax-Aufruf geliefert hat.

function getData(){ 
    var promise = $.ajax({ 
     url: 'api.php', 
     type: 'POST', 
     dataType: 'json' 
    }); 
    return promise.done(function(data){ 
     console.log(data); 
     if(data.errorCode === 0){ 
      return data; 
     } else { 
      return 'failed'; 
     } 
    }); 
} 
$(document).ready(function(){ 
    $('.btn').click(function(){ 
     var apiData = getData(); 
     console.log(apiData); 
    }); 
}); 

Also, wenn der api einen Fehlercode zurückgibt, der die Funktion getData nicht 0 ist, dann ist, sollte eine Reihe von ‚nicht bestanden‘ zurückzukehren, außer es das Datenelement zurückgibt. Ich weiß, dass der Code nicht 0 ist, weil die console.log zeigt, dass der Code 999 ist. Was mache ich falsch? Warum kann ich es nicht bekommen, um meine Kette von "gescheitert" zurückzugeben?

+2

Beitrag, wie Sie getData verwenden. – dfsq

+1

Was dfsq gesagt hat. Insbesondere, wenn Sie 'if (getData() ==" gescheitert ") und erwarten, dass dies darauf hinweist, dass es fehlgeschlagen ist, ist das das Problem. 'getData' gibt ein * Versprechen * (die jQuery-Variante) zurück, nicht" data "oder" failed "'. –

+2

Sie können nie direkt von einem asynchronen Anruf zurückkehren. Versprechen sind keine Magie, die das weniger wahr macht. Der Aufrufer von 'getData()' hat nicht sofort Zugriff auf das Ergebnis. Am besten können Sie Ihre Logik von * innerhalb * eines Rückrufs fortsetzen. Ob Sie Promises verwenden oder nicht, das ist der Fall. –

Antwort

2

getData nicht (und kann nicht) die Daten zurückgeben oder "failed"; es gibt eine Versprechen zurück. Sie verbrauchen dieses Versprechen viel wie Sie innerhalb getData tut:

$(document).ready(function(){ 
    $('.btn').click(function(){ 
     getData().done(function(apiData) { // ** 
      console.log(apiData);   // ** 
     });         // ** 
    }); 
}); 

In diesem Rückruf, apiData wird, was auch immer Ihr Rückruf in getData zurückgegeben, so dass es dann das Datenobjekt oder die Zeichenfolge "failed" sein.

(ich verwendet habe, done dort, weil es ist, was Sie an anderer Stelle verwendet, aber normalerweise würde ich then, die Standard-Versprechen-Funktion verwenden.)

Eines der wichtigsten Dinge über Versprechen zu verstehen ist, dass then (und done) gibt ein neues Versprechen (technisch, mit echten Versprechungen, ein thenable) zurück, die beruhend auf dem, was der Rückruf tut, abgerechnet wird.

So betrachten (lassen Sie uns mit jQuery-Stick jetzt latent):

function doSomething() { 
 
    var d = $.Deferred(); 
 
    setTimeout(function() { 
 
    // Resolve our promise with "a" 
 
    d.resolve("a"); 
 
    }, 10); 
 
    return d.promise(); 
 
} 
 

 
// Consume the promise and put it through a chain: 
 
doSomething() 
 
    .then(function(result) { 
 
    // This callback happens to do synchronous processing 
 
    console.log("First callback got", result); 
 
    return result.toUpperCase(); 
 
    }) 
 
    .then(function(result) { 
 
    // This one does something async, and so it returns a promise 
 
    var cd = $.Deferred(); 
 
    setTimeout(function() { 
 
     console.log("Second callback got", result); 
 
     cd.resolve(result + result); 
 
    }, 10); 
 
    return cd.promise(); 
 
    }) 
 
    .then(function(result) { 
 
    console.log("Third callback got", result); 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Der Ausgang davon ist

 
First callback got a 
Second callback got A 
Third callback got AA 

Nun, früher sagte ich then immer gibt ein Versprechen zurück (dann). Wie macht es das, wenn mein erster Rückruf synchron ist und einen Wert direkt zurückgibt, aber mein zweiter ist asynchron und gibt ein Versprechen zurück? Die Funktion then betrachtet den Rückgabewert des Callbacks und gibt, wenn es "thenable" ist (etwas mit then), es zurück; Wenn dies nicht möglich ist, wird ein neues, aufgelöstes Versprechen mit dem Wert als Auflösungswert erstellt.


Nur der Vollständigkeit halber, hier ist das obige Beispiel mit nativer JavaScript Versprechen (Browser-Unterstützung erfordert):

function doSomething() { 
 
    return new Promise(function(resolve) { 
 
    setTimeout(function() { 
 
     // Resolve our promise with "a" 
 
     resolve("a"); 
 
    }, 10); 
 
    }); 
 
} 
 

 
// Consume the promise and put it through a chain: 
 
doSomething() 
 
    .then(function(result) { 
 
    // This callback happens to do synchronous processing 
 
    console.log("First callback got", result); 
 
    return result.toUpperCase(); 
 
    }) 
 
    .then(function(result) { 
 
    // This one does something async, and so it returns a promise 
 
    return new Promise(function(resolve) { 
 
     setTimeout(function() { 
 
     console.log("Second callback got", result); 
 
     resolve(result + result); 
 
     }, 10); 
 
    }); 
 
    }) 
 
    .then(function(result) { 
 
    console.log("Third callback got", result); 
 
    });

Der Ausgang davon ist

 
First callback got a 
Second callback got A 
Third callback got AA 
0

Nach http://api.jquery.com/jquery.ajax/ documentati an, können Sie entweder .done, .fail, .always or .then ketten.

$(document).ready(function() { 
    $('.btn').click(function() { 
    $.ajax({ 
     url: 'api.php', 
     type: 'POST', 
     dataType: 'json' 
    }) 
    .done(function(data) { 
     console.log(data); 
     if (data.errorCode === 0) { 
      console.log(data) 
     } else { 
      console.log(data) 
     } 
    }); 
    }); 
}); 

Dies funktioniert