13 Stimmen

Warten auf die Beendigung des API-Aufrufs in Javascript vor dem Fortfahren

Etwas, mit dem ich in der Vergangenheit gekämpft habe und heute kämpfe, ist die Verhinderung einer API/AJAX von weiter, bis Sie Ihre Antwort erhalten haben. derzeit arbeite ich mit der Facebook-API. Ich muss eine Antwort von einem Aufruf erhalten und sie dann zurückgeben, aber was passiert, ist, dass meine Funktion zurückkehrt, bevor ich überhaupt eine Antwort von dem API-Aufruf erhalte. Ich weiß, warum das passiert, aber ich kann nicht herausfinden, wie ich das verhindern kann! Hier ist mein Code...

function makeCall(){

var finalresponse = "";
    var body = 'Test post';

      FB.api('/me/feed', 'post', { message: body }, function(response) {
        if (!response || response.error) {
         finalresponse = response.error;
        } else {
          finalresponse = 'Post ID: ' + response.id;
        }
      });
      return finalresponse;

}

----- EDIT

Mir ist aufgefallen, dass einige Leute etwas Ähnliches vorgeschlagen haben...

function makeCall(){
var finalresponse = "";
FB.api('/me/feed', 'post', { message: body }, function(response) {
        if (!response || response.error) {
         finalresponse = response.error;
         return finalresponse;
        } else {
          finalresponse = 'Post ID: ' + response.id;
          return finalresponse;
        }
      });
}

Aber das Ergebnis ist undefiniert

// BEARBEITUNG AUF DER GRUNDLAGE VON AKTUALISIERUNGEN

function share_share(action_id){

  var finalresponse = makeCall(action_id, process);
  return finalresponse;

}

function makeCall(action_id, callback){

var body = 'Test post';
      FB.api('/me/feed', 'post', { message: body }, function (response) {
        if (!response || response.error) {
         var finalresponse = response.error;
        } else {
          finalresponse = 'Post ID: ' + response.id;
        }
        callback(action_id, finalresponse);
      });

}
function process(action_id, finalresponse){
  console.log(finalresponse);
}

27voto

epascarello Punkte 194350

Die Frage, die 100 Mal am Tag gestellt wird und auf die es keine Antwort zu geben scheint.

Der Aufruf erfolgt asynchron, so dass es unmöglich ist, ihn in einem Schritt durchzuführen. Einfaches Beispiel für das, was Sie erwarten.

function one() {
  var a = 1;
  return a;
}
alert( one() );

Was tatsächlich geschieht:

function one() {
  var a;
  window.setTimeout( 
     function() {
        a = 1;
     }, 2000);
  return a;  //This line does not wait for the asynchronous call [setTimeout/ajax call] to run. It just goes!
}
alert( one() );

Sie müssen sie in zwei Teile aufteilen.

function one( callback ) {   
   window.setTimeout( function(){  //acting like this is an Ajax call
        var a = 1;
        callback(a);
   },2000);
}
function two( response ) {
   alert(response);
}
one( two );

In Ihrem Fall müssten Sie also Ihren Code aufteilen, um ihn in zwei Teilen zu behandeln.

function makeCall( callback ) {
    var body = 'Test post';
      FB.api('/me/feed', 'post', { message: body }, function (response) {
        if (!response || response.error) {
         var finalresponse = response.error;
        } else {
          finalresponse = 'Post ID: ' + response.id;
        }
        callback(finalresponse);
      });
}

function processResponse( response ) {
    console.log(response);
}
makeCall(processResponse);

7voto

Nadir Muzaffar Punkte 4700

In JavaScript gibt es kein Konzept des Wartens oder Nachgebens. JavaScript setzt die Ausführung Ihres Codes ohne Unterbrechung bis zum Ende fort. Das erscheint zunächst seltsam und lästig, hat aber auch seine Vorteile.

Die Idee in Szenarien wie diesem ist, dass der Code, den Sie nach dem Empfang Ihrer Antwort ausführen möchten, in den Callback, den Sie FB.api() geben, eingefügt werden sollte. Sie müssen den Code nach der Return-Anweisung in den Response-Callback ausgliedern, damit er ausgeführt werden kann, wenn die Antwort empfangen wird.

Das könnten Sie tun erwarten von JavaScript, wenn es wie die meisten Sprachen (wie C++/Java) wäre:

var futureResult = SomeAsyncCall();
futureResult.Wait(); //wait untill SomeAsyncCall has returned
var data = futureResult.GetData();
//now do stuff with data

Die Idee in JavaScript basiert jedoch auf Callbacks, wenn es um Asynchronität geht:

SomeAsyncCall(function(result) {
    var data = result.GetData();
    //now do stuff with data
});

3voto

Dave Rager Punkte 7737

Sie wollen nicht verhindern, dass sie zurückgegeben wird, da dies den Browser des Benutzers für die Dauer der Anfrage blockieren würde. Wenn die Anfrage aus irgendeinem Grund hängen bleibt (Überlastung, Wartung der Website usw.), reagiert der Browser nicht mehr auf Benutzereingaben, was zu verärgerten Benutzern führt.

Anstatt das Folgende zu tun:

var res = makeCall();
if(res)
{
   // do stuff
}

Tun Sie dies:

function makeCall(){
    FB.api('/me/feed', 'post', { message: body }, function(response) {
        if (response && !response.error) {
            // do stuff
        }
    });
}

makeCall();

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X