javascript 为什么这个函数不等到它有来自 XHR 请求的数据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16080655/
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
Why is this function not waiting until it has data from XHR request?
提问by Ian Tearle
When I call for getCurrentConditions it tries to return data before requestData has completed and therefore doesn't find data.currently. I am definately getting data returned from the URL, I have tried adding a timeout loop to wait for the XHR to load, but that just broke the script all together. I am kind of confused why the second function is not waiting for this.requestData(latitude, longitude); to finish before continuing.
当我调用 getCurrentConditions 时,它会尝试在 requestData 完成之前返回数据,因此找不到 data.currently。我肯定是从 URL 返回数据,我尝试添加一个超时循环来等待 XHR 加载,但这只是破坏了脚本。我有点困惑为什么第二个函数不等待 this.requestData(latitude, longitude); 在继续之前完成。
this.requestData = function(latitude, longitude) {
request_url = self.API_ENDPOINT + api_key + '/' + latitude + ',' + longitude + '?units=auto';
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState==4 && xhr.status==200) {
content = xhr.responseText;
if(content != '' && (content)) {
return JSON.parse(content);
} else {
return false;
}
}
}
xhr.open('GET', 'proxy.php?url='+request_url, true);
xhr.send(null);
}
/**
* Will return the current conditions
*
* @param float $latitude
* @param float $longitude
* @return \ForecastIOConditions|boolean
*/
this.getCurrentConditions = function(latitude, longitude) {
data = this.requestData(latitude, longitude);
if(data !== false) {
return new ForecastIOConditions(data.currently);
} else {
return false;
}
}
var forecast = new ForecastIO(api_key);
var condition = forecast.getCurrentConditions(latitude, longitude);
回答by Arun P Johny
Because ajax is asynchronous, means once the request is sent it will continue executing without waiting for the response.
因为 ajax 是异步的,意味着一旦发送请求,它将继续执行而无需等待响应。
One easy solution is to turn off the asynchronous nature by passing the 3rd parameter to the .open()method as false, but it has drawbacks like the browser thread will be blocked till the request is completed means UI will remain unresponsive till the request is completed.
一个简单的解决方案是通过将第三个参数传递给.open()方法作为 false来关闭异步特性,但它有缺点,比如浏览器线程将被阻塞直到请求完成意味着 UI 将保持无响应直到请求被完全的。
xhr.open('GET', 'proxy.php?url='+request_url, false);
The correct solution will be is to use a callback method
正确的解决方案是使用回调方法
this.requestData = function(latitude, longitude, callback) {
request_url = self.API_ENDPOINT + api_key + '/' + latitude + ',' + longitude + '?units=auto';
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState==4 && xhr.status==200) {
content = xhr.responseText;
if(content != '' && (content)) {
callback(JSON.parse(content));
} else {
callback(false);
}
}
}
xhr.open('GET', 'proxy.php?url='+request_url, true);
xhr.send(null);
}
/**
* Will return the current conditions
*
* @param float $latitude
* @param float $longitude
* @return \ForecastIOConditions|boolean
*/
this.getCurrentConditions = function(latitude, longitude, callback) {
this.requestData(latitude, longitude, function(data) {
if(data !== false) {
callback(ForecastIOConditions(data.currently));
} else {
callback(false);
}
});
}
var forecast = new ForecastIO(api_key);
forecast.getCurrentConditions(latitude, longitude, function(condition){
if(condition !== false) {
} else {
}
});
回答by Naveenkumar K
instead of
代替
xhr.open('GET', 'proxy.php?url='+request_url, true);
use
利用
xhr.open('GET', 'proxy.php?url='+request_url, false);
About method:
关于方法:
open(method,url,async)
Specifies the type of request, the URL, and if the request should be handled asynchronously or not.
指定请求的类型、URL 以及是否应异步处理请求。
method:
the type of request: GET or POST
method:
请求类型:GET 或 POST
url:
the location of the file on the server
url:
文件在服务器上的位置
async:
true (asynchronous) or false (synchronous)
async:
true(异步)或 false(同步)
Source: w3schools
资料来源:w3schools
回答by Pranay Rana
put false
instead of true
here
把false
而不是在true
这里
// `false` makes the request synchronous
xhr.open('GET', 'proxy.php?url='+request_url, false);
this make call Synchronous instead of aSynchronous. so when call become Synchronous its wait for ajax call to complete and than execute the function you want.
这使调用同步而不是同步。因此,当调用变为同步时,它会等待 ajax 调用完成,然后执行您想要的函数。
Mozila link for XMLHttpRequest: Synchronous and asynchronous requests
XMLHttpRequest 的 Mozila 链接:同步和异步请求
回答by Dmitry Volokh
It's asynch call. Try to use callback function. Code below is a sample. Not tested!
这是异步调用。尝试使用回调函数。下面的代码是一个示例。未测试!
this.requestData = function(latitude, longitude, callback) {
request_url = self.API_ENDPOINT + api_key + '/' + latitude + ',' + longitude + '?units=auto';
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState==4 && xhr.status==200) {
content = xhr.responseText;
if(content != '' && (content)) {
callback(JSON.parse(content));
} else {
return false;
}
}
}
xhr.open('GET', 'proxy.php?url='+request_url, true);
xhr.send(null);
}
/**
* Will return the current conditions
*
* @param float $latitude
* @param float $longitude
* @return \ForecastIOConditions|boolean
*/
this.getCurrentConditions = function(latitude, longitude) {
this.requestData(latitude, longitude, callback);
}
this.callback = function(data) {
if(data !== false) {
return new ForecastIOConditions(data.currently);
} else {
return false;
}
};