1. $q
$q
是Angular
的一种内置服务,它可以使你异步地执行函数,并且当函数执行完成时它允许你使用函数的返回值(或异常)。
2. defer
defer
的字面意思是延迟,$q.defer()
可以创建一个deferred
实例(延迟对象实例)。
deferred
实例旨在暴露派生的Promise
实例,以及被用来作为成功完成或未成功完成的信号API
,以及当前任务的状态。这听起来好复杂的样子,总结$q
, defer
, promise
三者之间的关系如下所示。
var deferred = $q.defer(); //通过$q服务注册一个延迟对象 deferred
var promise = deferred.promise; //通过deferred延迟对象,可以得到一个承诺promise,而promise会返回当前任务的完成结果
defer
的方法:
-
deferred.resolve(value)
成功解决(resolve
)了其派生的promise
。参数value
将来会被用作promise.then(successCallback(value){...}
,errorCallback(reason){...}
,notifyCallback(notify){...})
中successCallback
函数的参数。 -
deferred.reject(reason)
未成功解决其派生的promise
。参数reason
被用来说明未成功的原因。此时deferred
实例的promise
对象将会捕获一个任务未成功执行的错误,promise.catch(errorCallback(reason){...})
。补充一点,promise.catch(errorCallback)
实际上就是promise.then(null, errorCallback)
的简写。 -
notify(value)
更新promise
的执行状态(翻译的不好,原话是provides updates on the status of the promise's execution
)
defer
的小例子:
function asyncGreet(name) {
var deferred = $q.defer(); //通过$q.defer()创建一个deferred延迟对象,在创建一个deferred实例时,也会创建出来一个派生的promise对象,使用deferred.promise就可以检索到派生的promise。
deferred.notify('About to greet ' + name + '.'); //延迟对象的notify方法。
if (okToGreet(name)) {
deferred.resolve('Hello, ' + name + '!'); //任务被成功执行
} else {
deferred.reject('Greeting ' + name + ' is not allowed.'); //任务未被成功执行
}
return deferred.promise; //返回deferred实例的promise对象
}
function okToGreet(name) {
//只是mock数据,实际情况将根据相关业务实现代码
if(name == 'Superman') return true;
else return false;
}
var promise = asyncGreet('Superman'); //获得promise对象
//promise对象的then函数会获得当前任务也就是当前deferred延迟实例的执行状态。它的三个回调函数分别会在resolve(), reject() 和notify()时被执行
promise.then(function(greeting) {
alert('Success: ' + greeting);
}, function(reason) {
alert('Failed: ' + reason);
}, function(update) {
alert('Got notification: ' + update);
});
3. promise
当创建一个deferred
实例时,promise
实例也会被创建。通过deferred.promise
就可以检索到deferred
派生的promise
。
promise
的目的是允许interested parties
访问deferred
任务完成的结果。
按照CommonJS
的约定,promise
是一个与对象交互的接口,表示一个动作(action
)的结果是异步的,而且在任何给定的时间点上可能或不可能完成。(这句话好绕口,我的理解是promise
相当于一个承诺,承诺你这个任务在给定的时间点上可能会完成,也可能完成不了。如果完成了那就相当于resolve
, 如果未完成就相当于reject
。不知道这样理解对不对?)
promise
的方法:
then(successCallback, errorCallback, nitifyCallback)
根据promise
被resolve/reject
,或将要被resolve/reject
,调用successCallback/errorCallback
。catch(errorCallback) then(null, errorCallback)
的缩写。finally(callback, notifyCallback)
补充说明:
promise.then()
会返回一个新的衍生promise
,形成promise
链。例如:
promiseB = promiseA.then(function(result) {
return result + 1;
});
// promiseB will be resolved immediately after promiseA is resolved and its value
// will be the result of promiseA incremented by 1