2012-06-12 192 views
6

我过去一直在努力的事情,今天正在努力阻止API/AJAX继续,直到您收到您的回复。目前我正在使用Facebook API。我需要从一个调用得到响应然后返回它,但是发生的事情是我的函数在我从API调用得到响应之前返回。我知道为什么会发生,我无法弄清楚如何防止它!这里是我的代码...在继续之前等待API调用以Javascript完成之前

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

但这返回undefined

//根据更新编辑

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

我相信因为你的'return finalresponse;'在API调用之外。 –

+0

您的退货将在FB.api完成之前执行 – Dhiraj

+0

您在编辑中提供的代码不正确。在回调中返回finalResponse将返回给您的回复回调的调用者。未定义的原因返回给makeCall()的调用者是因为make call没有返回任何东西。 –

回答

13

被要求每天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); 
+1

而@Pointy只是杀了我的编辑,有时间再次重做。 – epascarello

+0

谢谢,这真的帮助我理解,但如果我想将回复返回给原始调用呢?看到我上面的最后编辑。我想获得价值并将其退回。所以基本上我有一个函数调用share_share,它需要返回一个响应。 –

+0

它不能只是返回,它必须是回调。 “回归最终答案”与以前一样,只是以不同的方式! – epascarello

6

在JavaScript中,没有等待或屈服的概念。 JavaScript将继续执行,而不会中断代码的执行。起初看起来很奇怪和麻烦,但它有其优点。

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

这就是你可能期望从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 
}); 
+0

感谢您的时间,你有什么建议来完成这个? –

+0

我添加了一个例子来澄清这个想法。 –

0

你不想从返回它在做这样的事情将阻止用户对请求期间浏览器来防止。如果请求因任何原因(拥塞,网站维护等等)挂起,则浏览器将无法响应任何导致用户不安的用户输入。

而不是做以下几点:

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(); 
相关问题