等待 API 调用在 Javascript 中完成,然后再继续



我过去一直在努力解决的问题,今天正在努力阻止API/AJAX继续,直到您收到响应为止。 目前我正在使用Facebook API。我需要从调用中获取响应然后返回它,但发生的事情是我的函数在我从 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);
}

每天被问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);

在 JavaScript 中,没有等待或屈服的概念。JavaScript 继续执行,而不会中断您的代码,直到其结束。乍一看似乎很奇怪很麻烦,但它有其优点。

因此,在这种情况下

的想法是,您希望在收到响应后执行的代码应放入您提供给 FB.api() 的回调中。您必须将 return 语句之后的代码分解为响应回调,以便在收到响应时可以执行它。

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

您不想阻止返回它,因为执行此类操作会在请求期间阻止用户的浏览器。如果请求因任何原因(拥塞、站点维护等)而挂起,浏览器将对任何用户输入无响应,从而导致用户不高兴。

而不是执行以下操作:

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

最新更新