获取AJAX获取数据
异步使用JavaScript和XML方式获取数据的方法叫做Ajax。
源数据
http://api.worldbank.org/regions/?format=json
[{
"page": "1",
"pages": "1",
"per_page": "50",
"total": "48"
},
[{
"id": "",
"code": "AFR",
"name": "Africa"
}, {
"id": "",
"code": "ANR",
"name": "Andean Region"
}, {
"id": "",
"code": "ARB",
"name": "Arab World"
}]
}]
第一个对象通过一个大的数据集合来支持翻页的功能,第二个元素是一个数组,里面是我们需要的信息。
通过Ajax获得第一层的数据
我们使用jsonp的方式去请求数据,但是jsonp有一个短处,就是没有一个表明服务错误的方法。
但是jQuery可以让我们用$.Deferred
对象来写的更加优雅一些。一旦Deferred对象被创建,当事件完成时,它会改变事件的状态,然后根据状态调用不同的回调函数。
var deferredRegionsRequest = $.getJSON(
"http://api.worldbank.org/regions/?prefix=?",
{format: "jsonp"}
);
然后我们就可以处理相应的代码了
deferredRegionsRequest.done(function(reponse){
// do something with response
})
这个done方法时Deferred对象的关键,它指定了一个新函数,这个函数是每当事件成功完成时我们想要执行的代码。
deferredRegionsRequest.done(function(reponse){
regions = $.map(
$.grep(reponse[1], function(regionObj){
return (regionObj.id !== null);
}),
function(regionObj) {
return {
code : regionObj.code,
name : regionObj.name.replace(" (all income levels)","")
};
}
);
});
我们只需要code和name属性。
获取实际数据
我们已经获取了地区的列表,但是这不是我们想要可视化的数据。我们需要再次去请求数据。
我们创建自己的Deferred对象。
var deferredRegionsAvailable = $.Deferred();
然后我们就可以调用对象的resolve()方法来指明状态。
deferredRegionsAvailable.resolve();
实际的处理还是通过done()方法。
var deferredRegionsRequest = $.getJSON(
"http://api.worldbank.org/regions/?prefix=?",
{format: "jsonp"}
);
var deferredRegionsAvailable = $.Deferred();
deferredRegionsRequest.done(function(response){
regions = $.map(
$.grep(response[1], function(regionObj){
return (regionObj.id !== null);
}),
function(regionObj) {
return {
code : regionObj.code,
name : regionObj.name.replace(" (all income levels)","")
};
}
);
});
deferredRegionsAvailable.done(function(regions){
}
我们首先请求一个地区列表,然后我们创建了第一个Deferred对象来追踪响应的进程,我们处理请求的响应,在接收进程完成的信号时处理第二个deferred对象,最后开始处理响应。
deferredRegionsAvailable.done(function(regions){
$.each(regions, function(idx, regionObj){
regionObj.deferredRegionsDataRequest = $.getJSON(
"http://api.worldbank.org/countries/" + regionObj.code + "/indicators/NY.GDP.MKTP.CD" + "?prefix=?",
{
format:"jsonp",
per_page:9999
}
);
});
});
在每个请求中都带有NY.GDP.MKTP.CD,是世界银行表示GDP数据的代码。
当每次这个循环过程完成时我们将创建一个deferred对象用来追踪。
regionObj.deferredRegionsDataAvailable = $.Deferred();
regionObj.deferredRegionsDataRequest.done(function(response){
regionObj.rawData = response[1] || [];
regionObj.deferredRegionsAvailable.resolve();
});
处理数据
现在我们已经请求到了实际的数据,接下来我们开始进行处理数据了,但是我们需要等待数据请求完以后才能开始处理。
由于在循环中会得到多个请求,可以使用.when()
函数。这个函数接收一个deferred对象的列表并且支持当前所有对象都成功后才能表示函数成功。
$.when.apply(this, $.map(regions, function(regionObj){
return regionObj.deferredRegionsDataAvailable;
})).done(function(){
deferredRegionsDataAvailable.resolve(regions);
})
当我们拿到数据时,我们可以将其转化为Flot接收的数据格式。
deferredAllDataAvailable.done(function(regions){
//console.log(regions);
$.each(regions, function(idx, regionObj){
//console.log(regionObj);
regionObj.fotData = $.map(
$.grep(regionObj.rawData, function(dataObj){
return (dataObj.value !== null);
}),
function(dataObj) {
return [[parseInt(dataObj.date), parseFloat(dataObj.value)/1e12]];
}
)
})
deferredChartDateReady.resolve(regions);
});
使用.each()函数循环地区列表。
创建图表
deferredChartDateReady.done(function(regions){
//console.log(regions);
$.plot($("#chart"),
$.map(regions, function(regionObj){
return {
label : regionObj.name,
data : regionObj.flotData
};
}),
{
legend:{ position: "nw"}
}
);
});
[
整个的处理过程如同跳跃一样。
全部代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/flot/0.8.3/jquery.flot.min.js"></script>
<title>Document</title>
</head>
<body>
<div id="chart" style="width: 600px;height: 400px;"></div>
<script>
$(function(){
var deferredRegionsRequest = $.getJSON(
"http://api.worldbank.org/regions/?prefix=?",
{format: "jsonp"}
);
var deferredRegionsAvailable = $.Deferred();
//开始进行处理
deferredRegionsRequest.done(function(response){
deferredRegionsAvailable.resolve(
regions = $.map(
$.grep(response[1], function(regionObj){
return (regionObj.id !== "");
}),
function(regionObj) {
return {
code : regionObj.code,
name : regionObj.name.replace(" (all income levels)","")
};
}
)
);
});
var deferredAllDataAvailable = $.Deferred();
deferredRegionsAvailable.done(function(regions){
$.each(regions, function(idx, regionObj){
regionObj.deferredRegionsDataRequest = $.getJSON(
"http://api.worldbank.org/countries/" + regionObj.code + "/indicators/NY.GDP.MKTP.CD" + "?prefix=?",
{
format:"jsonp",
per_page:9999
}
);
regionObj.deferredRegionsDataAvailable = $.Deferred();
regionObj.deferredRegionsDataRequest.done(function(response){
regionObj.rawData = response[1] || [];
regionObj.deferredRegionsDataAvailable.resolve();
});
});
$.when.apply(this, $.map(regions, function(regionObj){
return regionObj.deferredRegionsDataAvailable
})).done(function(){
deferredAllDataAvailable.resolve(regions);
});
});
var deferredChartDateReady = $.Deferred();
deferredAllDataAvailable.done(function(regions){
//console.log(regions);
$.each(regions, function(idx, regionObj){
//console.log(regionObj);
regionObj.flotData = $.map(
$.grep(regionObj.rawData, function(dataObj){
return (dataObj.value !== null);
}),
function(dataObj) {
return [[parseInt(dataObj.date), parseFloat(dataObj.value)/1e12]];
}
)
})
deferredChartDateReady.resolve(regions);
});
deferredChartDateReady.done(function(regions){
console.log(regions);
$.plot($("#chart"),
$.map(regions, function(regionObj){
return {
label : regionObj.name,
data : regionObj.flotData
};
}),
{
legend:{ position: "nw"}
}
);
});
});
</script>
</body>
</html>