假如想运用 $http 或许其他异步操纵, 那 $q 是必须要控制的观点啦. Let’s get started!
怎样明白$q, deferred object ?
假定有一个家具厂,而它有一个VIP客户张先生。
有一天张先生须要一个奢华衣柜,因而,他打电话给家具厂说我须要一个衣柜,转头做好了给我送来,这个操纵就叫$q.defer,也就是延期,由于这个衣柜不是如今要的,所以张先生这是在提议一个可延期的请求。
同时,家具厂给他留下了一个回执号,并对他说:我们做好了会给您送过去,宁神吧。这叫做promise,也就是许诺。
如许,这个defer算是正式建立了,因而他把这件事记录在自身的日记上,而且同时记录了回执号,这叫做deferred,也就是已延期事宜。
如今,张先生就不必再去想着这件事了,该做什么做什么,这就是“异步”的寄义。
假定家具厂在一周后做完了这个衣柜,并履约送到了张先生家(包邮哦,亲),这就叫做deferred.resolve(衣柜),也就是“已处置惩罚”。而这时刻张先生只需签收一下这个(衣柜)参数就好了,固然,这个“邮包”中也不一定只要衣柜,还能够包括别的东西,比方厂家宣扬材料、产物名录等。全部过程当中轻松愉快,谁也没等谁,没有糟蹋任何时候。
假定家具厂在评价后发明这个规格的衣柜我们做不了,那末它就须要deferred.reject(来由),也就是“谢绝”。谢绝没有时候限定,能够发作在给出许诺以后的任何时刻,以至能够发作在快做完的时刻。而且谢绝时刻的参数也不仅仅限于来由,还能够包括一个道歉信,违约金之类的,总之,你想给他什么就给他什么,假如你以为不会触怒客户,那末不给也没紧要。
假定家具厂发明,自身正好有一个相符张先生请求的存货,它就能够用$q.when(现有衣柜)来把这个许诺给张先生,这件事就马上被处置惩罚了,大快人心,张先生可不在意你是从新做的照样现有的制品,只会赞叹于你们的效力之高。
假定这个家具厂对客户分外的仔细,它还能够经由过程deferred.notify(愿望状况)给张先生发送愿望状况的“关照”。
如许,全部异步流程就圆满完成,不管胜利或许失利,张先生都没有往里面投入任何分外的时候本钱。
好,我们再扩大一下这个故事:
张先生此次须要做一个桌子,三把椅子,一张席梦思,然则他不愿望本日收到个桌子,来日诰日收到个椅子,后天又得签收一次席梦思,而是愿望家具厂做好了以后一次性送过来,然则他下单的时刻又是离别下单的,那末他就能够从新跟家具厂要一个包括上述三个许诺的新许诺,这就是$q.all(桌子许诺,椅子许诺,席梦思许诺),
如许,他就不必再关注之前的三个许诺了,直接守候这个新的许诺完成,到时刻只需一次性签收了前面的这些许诺就好了。
怎样建立 promise -1
$q 支撑两种写法, 第一种是类似于ES6规范组织函数写法
$q(function resolver (resolve, reject) {})
注重:
+ ES6 写法并不支撑 progress/notify 的回调函数
+ 在组织函数中抛非常也并不会显式的reject the promise
// var iWantResolve = false;
var iWantResolve = true;
function es6promise() {
return $q(function (resolve, reject) {
$timeout(function () {
if (iWantResolve) {
resolve("es6promise resolved");
} else {
reject("es6promise reject");
}
}, 1000)
})
}
promise 的要领
promise.then(successCb, errCb, notifyCb)
个中successCb 将在 promise resolve 后被挪用, errCb 将在 promise reject 后被调
notifyCb 将在 deferred.notify 后被挪用, 能够屡次挪用
promise.catch == promise.then(null, errCb), 用于处置惩罚之前没有被处置惩罚的 rejected promise
promise.finally 将末了被挪用, 平常用于资本开释的清算操纵
es6promise()
.then(function (data) {
console.log(data);
})
.catch(function (err) {
console.log(err);
});
// if(iWantResolve == true) output: es6promise resolved
// if(iWantResolve = false) output: es6promise reject
怎样建立 promise -2
第二种是类似于 commonJS 的写法 $q.deferred()
function commonJsPromise() {
var deferred = $q.defer();
$timeout(function () {
deferred.notify("commonJS notify");
if (iWantResolve) {
deferred.resolve("commonJS resolved");
} else {
deferred.reject("commonJS reject");
}
}, 500);
return deferred.promise;
}
commonJsPromise()
.then(function /** success callback**/(data) {
console.log(data);
}, function /** error callback **/ (err) {
console.log(err);
}, function /** progress callback **/ (update) {
console.log(update);
});
// if(iWantResolve == true) output: commonJS notify commonJS resolved
// if(iWantResolve = false) output: commonJS notify commonJS reject
$q.all
$q.all([promise1, promise1])
接收一个包括若干个 promise 的数组,等一切的 promise resolve 后, 其自身 resolve 包括上述效果的数组 [data1, data2]
假如上述 promise 有一个 reject, 那末$q.all() 会把这个 rejected promise 作为其 rejected promise (只要一个哦)
progress/notify 的 callback 并没有效
$q.all([es6promise(), commonJsPromise()])
.then(function (dataArr) {
console.log("$q.all: ", dataArr);
}, function (err) {
console.log("$q.all: ", err)
}, function /** unnecessary **/ (update) {
console.log("$q.all", update);
});
// if(iWantResolve == true) output: $q.all: ["es6promise resolved", "commonJS resolved"]
// if(iWantResolve = false) output: $q.all: es6promise reject
$q.reject, $q.when, $q.resolve
$q.reject() 马上返回一个rejected 的 promise, 在链式挪用的时刻很有效
$q.resolve == $q.when(value, successCb, errorCb, progressCb)
value 多是一个 then-able 的 obj(即能够是 $q.defer() 返回的, 也能够是其他库发生的), 也多是恣意数据, 然则 $q.when 终究都邑返回一个 promise
$q.when 既能够写成上述的组织函数情势, 也能够写成 $q.when(value).then(fn, fn, fn) 的情势
$q.reject("instant reject")
.catch(function (err) {
console.log(err);
});
// output: instant reject
$q.when(commonJsPromise(),
function /** success callback **/(data) {
console.log("$q.when success callback function: " + data);
return "$q.when success callback return another value";
})
.then(function (data) {
console.log("$q.when then function:" + data);
});
// if(iWantResolve == true) output:
// $q.when success callback functionL: commonJS resolved
// $q.when then function:$q.when success callback return another value
// if(iWantResolve = false) output:
// $q.when err callback function: commonJS reject
// $q.when then function:undefined
$q.when("some value", function (data){
console.log(data);
})
// output: some value
promise chains 链式挪用
任安在 successCb, errCb 中返回的非 $q.reject()对象, 都将成为一个 resolve 的 promise.
所以能够涌现以下语法 promise.then().then().then()
$q.when("1")
.then(function (data) {
console.log(data);
return $q.reject(2);
})
.catch(function (err) {
console.log(err);
return 3;
})
.then(function (data) {
console.log(data);
})
// output: 1 2 3