在继续之前等待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; } }); } 

但这会返回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); } 

这个问题每天被问到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语句放入响应回调之后,您必须将代码分解出来,以便在收到响应时执行该代码。

如果像大多数语言(例如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 }); 

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

而不是做以下事情:

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