2012-06-12 13 views
6

coś, z czym borykałem się w przeszłości i zmagam się z dzisiejszymi problemami, uniemożliwia kontynuowanie interfejsu API/AJAX, dopóki nie otrzymasz odpowiedzi. obecnie pracuję z interfejsem API Facebooka. Muszę uzyskać odpowiedź z połączenia, a następnie ją zwrócić, ale to, co się dzieje, to to, że moja funkcja wraca, zanim otrzymam odpowiedź z wywołania API. Wiem, dlaczego to się dzieje, po prostu nie mogę wymyślić, jak temu zapobiec! Oto mój kod ...Oczekiwanie na wywołanie API w języku Javascript przed kontynuowaniem

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

zauważyłem niektórzy ludzie zasugerował coś takiego ...

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; 
     } 
     }); 
} 

Ale to zwraca niezdefiniowana

// EDYCJA OPARTA NA AKTUALIZACJI

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); 
} 
+0

Wierzę, ponieważ twoja 'return finalresponse;' jest poza wywołaniem API. –

+0

Twój powrót zostanie wykonany, zanim FB.api zakończy – Dhiraj

+0

kod podany podczas edycji jest niepoprawny. Zwrócenie ostatecznej odpowiedzi w twoim oddzwonieniu zostanie zwrócone do dzwoniącego oddzwonionego z odpowiedzi. Powód niezdefiniowany jest zwracany do wywołującego dla makeCall(), ponieważ wywołanie nie zwraca niczego. –

Odpowiedz

13

pytanie, które zadawane jest 100 razy dziennie i wydaje się niemożliwe, aby mieć jedną odpowiedź.

Połączenie jest asynchroniczne, więc nie można tego wykonać w jednym kroku. Podstawowy przykład tego, czego oczekujesz.

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

Co się rzeczywiście dzieje:

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()); 

Co trzeba zrobić, to podzielić ją na dwie części.

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); 

W twoim przypadku musisz podzielić kod na dwie części.

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); 
+1

A @Pointy właśnie zabił moją edycję, czas na jej ponowienie. – epascarello

+0

Dzięki, to naprawdę pomogło mi zrozumieć, ale co jeśli chcę zwrócić odpowiedź na pierwotne połączenie? Zobacz moją ostatnią edycję powyżej. Chciałbym uzyskać wartość i zwrócić ją. Więc zasadniczo mam funkcję, która wywołuje share_share i musi zostać zwrócona z odpowiedzią. –

+0

Nie można go tylko zwrócić, musi to być wywołanie zwrotne. 'Return finalresponse;' to to samo co wcześniej, tylko w inny sposób! – epascarello

6

W języku JavaScript nie ma koncepcji oczekiwania ani plonowania. JavaScript kontynuuje nieprzerwane wykonywanie kodu do końca. Z początku wydaje się to dziwne i kłopotliwe, ale ma swoje zalety.

Tak więc w scenariuszach takich jak ten, kod, który chcesz wykonać po otrzymaniu odpowiedzi, powinien zostać wprowadzony do wywołania zwrotnego, które dajesz FB.api(). Będziesz musiał złamać kod po instrukcji return w odpowiedzi zwrotnej, aby można było wykonać ją po otrzymaniu odpowiedzi.

To co można oczekiwać z JavaScript gdyby było tak jak większość języków (takie jak C++/Java):

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

Pomysł w JavaScripcie, jednak opiera się callbacków gdy ma do czynienia z asynchrony :

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

dziękuję za poświęcony czas, czy masz jakieś sugestie, aby to osiągnąć? –

+0

Dodałem przykład, aby wyjaśnić ten pomysł. –

0

nie chcesz, aby zapobiec powrotowi go jak robi coś takiego będzie blokować przeglądarkę użytkownika na czas trwania wniosku. Jeśli żądanie zostanie zawieszone z dowolnego powodu (przeciążenie, konserwacja witryny itp.), Przeglądarka przestanie reagować na wszelkie dane wejściowe użytkownika, powodując zakłócenia użytkowników.

Zamiast wykonując następujące czynności:

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

Wykonaj:

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

makeCall(); 
Powiązane problemy