在继续之前等待 API 调用在 Javascript 中完成
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11001318/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Waiting for API call to finish in Javascript before continuing
提问by G.Thompson
something I've struggled with in the past and am struggling with today is preventing an API/AJAX from continuing until you've recieved your response. currently I'm working with the Facebook API. I need to get a response from a call then return it but what's happening is that my function is returning before I ever get a response from the API call. I know why it's happening, I just can't figure out how to prevent it! Here's my code...
我过去一直在努力并且今天正在努力的事情是阻止 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;
}
// ----- EDIT
// - - - 编辑
I noticed some people suggested something like this...
我注意到有些人提出了这样的建议......
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;
}
});
}
But this returns undefined
但这返回未定义
// EDIT BASED ON UPDATES
// 基于更新的编辑
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);
}
回答by epascarello
The question that is asked 100 times a day and seems impossible to have one answer.
每天被问100次,似乎不可能有一个答案的问题。
The call is asynchronous so it is impossible to do it in one step. Basic example of what you expect.
调用是异步的,因此不可能一步完成。您期望的基本示例。
function one() {
var a = 1;
return a;
}
alert( one() );
What is actually happening:
实际发生的事情:
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() );
What you need to do is break it up into two parts.
你需要做的是把它分成两部分。
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 );
So in your case you would need to break up your code to handle it in two chunks.
因此,在您的情况下,您需要将代码分解成两块来处理它。
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);
回答by Nadir Muzaffar
In JavaScript, there is no concept of waiting or yielding. JavaScript continues execution, without interruption, of your code to its end. It seems weird and troublesome at first, but it has its advantages.
在 JavaScript 中,没有等待或让步的概念。JavaScript 会不间断地继续执行您的代码直到结束。乍一看似乎很奇怪和麻烦,但它有它的优点。
So the idea in scenarios such as this is that the code you wish to execute after receiving your response should be put into the callback that you give to FB.api(). You'll have to break out the code after your return statement into the response callback so that it can be executed when the response is received.
因此,在这种情况下的想法是,您希望在收到响应后执行的代码应放入您提供给 FB.api() 的回调中。您必须将 return 语句之后的代码分解到响应回调中,以便在收到响应时执行。
This is what you might expectfrom JavaScript if it were like most languages (such as C++/Java):
如果 JavaScript 与大多数语言(例如 C++/Java)一样,那么这就是您对JavaScript 的期望:
var futureResult = SomeAsyncCall();
futureResult.Wait(); //wait untill SomeAsyncCall has returned
var data = futureResult.GetData();
//now do stuff with data
The idea in JavaScript, however, is based around callbacks when dealing with asynchrony:
然而,JavaScript 中的想法是基于处理异步时的回调:
SomeAsyncCall(function(result) {
var data = result.GetData();
//now do stuff with data
});
回答by Dave Rager
You don't want to prevent from returning it as doing such a thing will block the user's browser for the duration of the request. If the request hangs for whatever reason (congestion, site maintenance, etc...) the browser will become unresponsive to any user input resulting in upset users.
您不想阻止返回它,因为这样做会在请求期间阻止用户的浏览器。如果请求因任何原因(拥塞、站点维护等)挂起,浏览器将对任何用户输入无响应,从而导致用户不安。
Instead of doing the following:
而不是执行以下操作:
var res = makeCall();
if(res)
{
// do stuff
}
Do this:
做这个:
function makeCall(){
FB.api('/me/feed', 'post', { message: body }, function(response) {
if (response && !response.error) {
// do stuff
}
});
}
makeCall();