Ожидание завершения вызова API в Javascript перед продолжением

То, с чем я боролся в прошлом и с чем борюсь сегодня, - это предотвращение продолжения API / AJAX до тех пор, пока вы не получите свой ответ. в настоящее время я работаю с API Facebook. Мне нужно получить ответ от вызова, а затем вернуть его, но происходит то, что моя функция возвращается до того, как я получу ответ от вызова API. Я знаю, почему это происходит, я просто не могу понять, как это предотвратить! Вот мой код ...

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;

}

// ----- РЕДАКТИРОВАТЬ

Я заметил, что некоторые люди предложили что-то вроде этого ...

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

Но это возвращает неопределенный

// РЕДАКТИРОВАТЬ НА ОСНОВЕ ОБНОВЛЕНИЙ

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);
}
 Nadir Muzaffar12 июн. 2012 г., 19:18
код, который вы указали при редактировании, неверен. Возвращение finalResponse в вашем обратном вызове будет возвращено вызывающей стороне вашего ответного обратного вызова. Причина undefined возвращается вызывающей стороне для makeCall (), потому что вызов make ничего не возвращает.
 Dhiraj12 июн. 2012 г., 19:03
Ваш возврат будет выполнен до завершения FB.api
 jezza-tan12 июн. 2012 г., 19:02
Я верю, потому что вашreturn finalresponse; находится за пределами вызова API.

Ответы на вопрос(3)

ыполнение вашего кода без прерывания до конца. Сначала это кажется странным и неприятным, но у него есть свои преимущества.

Таким образом, идея в таких сценариях заключается в том, что код, который вы хотите выполнить после получения вашего ответа, должен быть помещен в обратный вызов, который вы даете FB.api (). Вам придется разбить код после вашего оператора return на ответный обратный вызов, чтобы он мог быть выполнен при получении ответа.

Это то, что вы могли быexpect из JavaScript, если бы он был похож на большинство языков (таких как C ++ / Java):

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

Идея JavaScript, однако, основана на обратных вызовах при работе с асинхронностью:

SomeAsyncCall(function(result) {
    var data = result.GetData();
    //now do stuff with data
});
 12 июн. 2012 г., 19:21
Я добавил пример, чтобы прояснить идею.
 G.Thompson12 июн. 2012 г., 19:11
спасибо за ваше время, у вас есть какие-либо предложения для достижения этой цели?
Решение Вопроса

который задают 100 раз в день, и кажется невозможным получить один ответ.

Вызов асинхронный, поэтому невозможно сделать это за один шаг. Основной пример того, что вы ожидаете.

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

Что на самом деле происходит:

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

Что вам нужно сделать, это разбить его на две части.

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

Таким образом, в вашем случае вам нужно разбить код на две части.

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);
 12 июн. 2012 г., 19:20
И @Pointy только что убил мою правку, пора повторить ее еще раз.
 G.Thompson12 июн. 2012 г., 20:00
Спасибо, это действительно помогло мне понять, но что, если я хочу вернуть ответ на исходный вызов? Смотрите мое последнее редактирование выше. Я хотел бы получить значение и вернуть его. Так что в основном у меня есть функция, которая вызывает share_share, и она должна быть возвращена с ответом.
 G.Thompson12 июн. 2012 г., 20:21
так что я просто не могу делать то, что хочу? Разве невозможно вернуть ответ ajax / api родительской функции?
 12 июн. 2012 г., 20:59
Используйте, если это может быть сделано с синхронным вызовом, НО вы вызываете другой домен, поэтому он должен быть асинхронным. Вам нужно разбить логику на два этапа.
 12 июн. 2012 г., 20:20
Он не может быть просто возвращен, это должны быть обратные вызовы.return finalresponse; это то же самое, что вы имели раньше, просто по-другому!

так как при этом блокируется браузер пользователя на время запроса. Если запрос зависает по какой-либо причине (перегрузка, обслуживание сайта и т. Д.), Браузер перестает отвечать на любые действия пользователя, что приводит к расстройству пользователей.

Вместо того, чтобы делать следующее:

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

Сделай это:

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

makeCall();

Ваш ответ на вопрос