$q 实例分析angular中的promise

相信有一些开发经验的朋友就应该知道,对于JavaScript而言,promise十分重要,在开发中总能用到。因此掌握好它是一件必须做的事情。

我之前写过一篇文章,工作总结:jQuery高级应用之Deferred对象,介绍jquery中的promise,因此关于promise的基础介绍就不再详细讲解,这篇文章会重点关注angular中promise的实现。

我们首先有一个简单的html标签,下面的例子都会基于这个标签来书写

$q

在angular中,$q是一个非常重要的service。通过$q,angular有两种比较常用的方式来实现promise,分别是ES6风格与jquery风格。

ES6风格实现

我们直接来看看js代码

angular.module('app', [])
.controller('demoController', function($q, $timeout) {
var a = 1;
$q(function(resolve, reject) {
$timeout(function() {
if(a == 1) {
console.log('resolve');
resolve('hello, JAKE');
} else {
console.log('reject');
reject('JAKE is not here!')
}
}, 2000)
})
.then(function(greeting) {
console.log('success, ' + greeting);
}, function(reason) {
console.log('failed, ' + reason);
})
})
当a==1,输出结果为

"resolve"
"success, hello, JAKE"
当a!=1,输出结果为

"reject"
"failed, JAKE is not here!"
点我查看实例地址

上例中,我直接将第一步逻辑在$q()中处理。回调函数有两个参数,resolve, reject,分别代表执行成功与失败。

然后在对应的逻辑里面,使用resolve/reject标记逻辑的执行状态。then方法中的代码会在第一步的逻辑执行完了才执行,为了证明这一点,我在第一步的逻辑中设置了2秒的延迟。then会等待第一步执行完毕。

then有两个回调函数,分别表示执行成功和执行失败的回调,回调函数的参数为在第一步逻辑中标记方法传入的字符串。如果第一步逻辑执行成功,则会执行then第一个回调函数,如果失败,则会执行第二个回调。

jquery 风格

与jquery实现类似,我们需要定义个defer对象,并在第一步逻辑中手动返回promise

angular.module('app', [])
.controller('demoController', function($q, $timeout) {
var a = 1;

$q.when(function() {    var defer = $q.defer();    $timeout(function() {        defer.notify('notify jake.');        if(a == 1) {            console.log('rsolve');            defer.resolve('hello, jake');        }        else {            console.log('reject');            defer.reject('jake is not here.')        }    }, 2000);    return defer.promise;}()).then(function(greeting) {    console.log('success, ' + greeting);}, function(reason) {    console.log('fail, ' + reason);}, function(update) {    console.log('notify, ' + update);})

})
当a==1,输出结果为

"rsolve"
"notify, notify jake."
"success, hello, jake"
当a!=1 输出结果为

"reject"
"notify, notify jake."
"fail, jake is not here."
点击我查看实例

angular中,promise的一些方法

其实从上面的实例就已经能够知道promise的大概用法,不算复杂。

1. then(successCallback, errorCallback, notifyCallback)
从字面上我们就能够看出then三个回调的含义,第二个参数与第三个参数为可选。

2. catch(errorCallback)
相当于 then(null, errorCallback)

3. finally(callback, notifyCallback)
无论promise的返回状态是上面,该方法总是会执行。

链式操作

如果then中逻辑的执行需要时间等待,那么,then中回调函数的返回值为promise对象时,才能够按顺序执行。因此需要我们手动返回一个promise对象,例子如下

var app = angular.module('app', []);

app.controller('demoController', function($q, $timeout) {
$q.when(function() {
var defer = $q.defer();
$timeout(function() {
console.log('first');
defer.resolve();
}, 2000);
return defer.promise;
}())
.then(function() {
var defer = $q.defer();
$timeout(function() {
defer.resolve();
console.log('second');
}, 1000);
return defer.promise;
})
.then(function() {
console.log('third');
})
});

"first""second""third"

点我查看实例地址
官方文档中,认为then方法中只需要有返回值

但是如果then的执行不需要时间等待,then中的回调函数的第一个参数,会获取到上一个then的返回值,然后按顺序执行,如下例。

var app = angular.module('app', []);

app.controller('demoController', function($q, $timeout) {

function first() {    var a = 1;    var defer = $q.defer();    $timeout(function() {        if(a == 1) {            console.log('first resolve');            defer.resolve('resolve result');            } else {            console.log('first reject');            defer.reject();        }    }, 2000)    return defer.promise;}var promiseA = first();promiseA.then(function(result) {    // $timeout(function() {    console.log('second, ' + result);    return 'document';    // }, 1000)}).then(function(result) {    console.log('third, ' + result);})

});
输出结果为

"first resolve"
"second, resolve result"
"third, document"
点我查看实例地址

因为表述起来并不是那么容易,因此建议大家通过实例慢慢理解。

$http

$http是对promise的最佳实践。由于controller生命周期会在controller消亡的时候结束,其中的数据也会销毁,因此我们常常会将获取数据的操作放在自定义的服务中。因此我们的实例如下

angular.module('app', [])
.controller('demoController', function(data) {
data.getData().then(function(resp) {
console.log(resp);
})
})
.factory('data', function($http) {
return {
getData: function() {
var url = 'https://hq.tigerbrokers.com/fundamental/finance_calendar/get_day/2016-06-26';
return $http.get(url);
}
}
})
我们将then中回调函数的参数打印出来,发现格式如下

Object {
config: Object {},
data: Object {},
headers: function(d) {},
status: 200,
statusText: 'OK'
}
这一点与jquery的返回值略有不同,他们分别表示的意思为

config: 请求的配置信息
data: 返回的数据
headers: 请求的头部信息
status: 返回的状态码

点击查看实例地址

关键字:JavaScript, angularjs, html, html5

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部