11

我过去和今天都在努力解决的问题是阻止 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);
}
4

3 回答 3

21

每天被问 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);
于 2012-06-12T17:17:40.313 回答
7

在 JavaScript 中,没有等待或让步的概念。JavaScript 将继续执行您的代码,而不会中断。乍一看似乎很奇怪,很麻烦,但它有它的优点。

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

如果 JavaScript 与大多数语言(例如 C++/Java)一样,这就是您对 JavaScript 的期望:

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
});
于 2012-06-12T17:07:12.627 回答
4

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

而不是执行以下操作:

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();
于 2012-06-12T17:13:31.423 回答