http://wcp1231.logdown.com/posts/165232-angularjs-q-poll-chart-data
最近在做的项目中使用到了AngularJS,就做一个AngularJS的学习笔记。这次的内容是AngularJS的$q:提供了异步回调管理的服务。
起因
在项目中要做一个实时数据的图表展示,需要在页面上轮询请求后台数据并显示在图表中。
我使用的是Highcharts图表控件,从官网的动态更新DEMO中可以看到,图表数据的更新是通过配置中的load
事件做到的。
从后台获取数据可以通过AngularJS的$http
服务,那么剩下就是如何将获取到的数据添加到图表中了。
最简单的做法就是在load
事件中轮询请求服务器:
$(element).highcharts('StockChart', {
chart: {
events: {
load: function() {
var series = this.series[0];
var polling = function() {
$http.get('url-to-data').success(function(resp) {
series.addPoint(resp.data, true, true);
});
}
setInterval(polling, interval);
}
}
},
// 其他配置
};
但是项目中有多个图表并且一次请求的结果会返回所有图表的数据,不能在每个图表的load
事件里都请求数据。所以就得使用AngularJS提供的$q
异步回调管理服务了。
$q
服务介绍
$q
服务的基本用法是这样的:
- 通过
$q
得到一个deferred
实例 - 通过
deferred
实例的promise
属性得到promise
对象。 -
promise
实例负责定义回调函数 -
deferred
实例负责触发回调
下面分别说明上边提到的$q
、deferred
、promise
这三个对象:
一、promise
对象
promise
对象只有一个then
方法,有三个参数分别是:成功回调函数、失败回调函数、通知回调函数。并再返回promise
对象,用于链式调用。
var deferred = $q.defer(),
p1 = defer.promise;
var p2 = p1.then(
function(data) { console.log(value); return value + 1; },
function(data) { console.log('a') }
).then(
function(data) { console.log(value); return value + 1; },
function(data) { console.log('b') }
);
p2.then(
function(data) { console.log(value); return value + 1; },
function(data) { console.log('c') }
);
/*
* 调用 resolve(1) 的结果将是 1 2 3
* 可见,resolve 的参数将会传给 promise 里注册的函数,并且一个函数的返回将会传给后边的函数。
*/
deferred.resolve(1);
/*
* 值得注意的是,如果直接调用 reject(1) 得到的结果并不是 a b c 而是 a 1 2
* 也就是说第一个 promise 的失败回调函数并不会触发第二个 promise 的失败回调函数。
* 要想的到 a b c 的结果需要使用下面将要讲到的 $q.reject()
*/
那么通知回调函数
是什么呢?
上边代码中不论是resolve()
还是reject()
函数,在调用一次之后整个promise
调用链就失效了,所以再执行一次resolve()
是没有任何效果的。所以想要能多次调用就需要这个通知回调函数
了。
var deferred = $q.defer(),
p = deferred.promise;
p.then(
null,
null,
function(data) { console.log(0) }
).then(
null,
null,
function(data) { console.log(1) }
);
/*
* 通知回调函数得通过调用 notify() 触发。
* 像这样调用两次就会看到两次 0 1
*/
deferred.notify();
deferred.notify();
二、deferred
对象
deferred
对象有一个promise
属性和resolve
、reject
、notify
三个方法。
在上边例子中已经展示了这三个方法的用法,就不再说明了。
三、$q
$q
有三个方法,分别是:
all()
方法,接受一个promise
数组返回一个promise
对象。当数组中每一个promise
都完成后才执行返回的promise
中的内容。
$q.all([
$http.get('data-1'),
$http.get('data-2')
]).then(
function(datas) { console.log('ok ' + datas[0] + ' ' + datas[1]); },
function(datas) { console.log('error'); }
);
这样,then
里绑定的函数将会在data-1
和data-2
的异步请求结束后才执行。
上边promise
例子里提到了reject()
,这个函数就是用来触发下一次promise
的失败回调的
var deferred = $q.defer(),
p = defer.promise;
p.then(
null,
function() { console.log('a'); return $q.reject() }
).then(
null,
function() { console.log('b'); return $q.reject() }
);
/*
* 这样,调用 deferred.reject() 的结果就是 a b 了。
*/
deferred.reject();
when()
还没看懂没理解。
多图表实时数据
介绍了$q
服务和deferred
、promise
两个对象后,多个图表的实时监控就不难了。
总的来说,就是利用notify
可以多次调用实现的。