$q

一个帮助处理异步执行函数的服务。当他们做完处理时,使用它们的返回值(或异常)。

受 Kris Kowa’s Q 的启发,这是一个实现promise/deferred对象的启用。

$q的两种方式---这是一个更类似于Kris Kowal Q或jQuery的递延实现,另一种在一定程度上类似的ES6承诺。

Deferred Api

一个被$q.defer()调用的deferred的新实例。

deferred对象的目的是暴露相关承诺实例,以及APIs被执行的成功或不成功情况,以及任务的状态。

方法

resolve(value):根据value以解决派生的promise。如果值是通过$q.reject构造的rejection 对象,该promise将被拒绝。

reject(reason):根据reason以拒绝派生的promise。这相当通过 $q.reject构造的rejection 对象来解决。

notify(value):在 promise 被执行的过程中提供状态更新情况。这可能会被多次调用,在promise是被解决还是被拒绝之前。

属性

promise:承诺,与这个延迟相关的承诺对象。

Promise Api

当一个deferred实例被创建时,一个promise实例被创建,并且可以通过调用deferred.promise检索。Promise对象的目的是当它完成后允许需要的地方获得延迟任务的结果。

方法

then(successCallback,errorCallback,notifyCallback);

无论什么时候,promise是已经(将要)被解决或拒绝,只要结果是可用的,就调用一个成功/错误的回调异步。回调函数带着一个参数被调用:解决的结果或拒绝的原因。此外,在承诺被解决或被拒绝之前,通知回调可能被调用0或多次用来提供一个指示进度。

这个方法返回被successCallback/errorCallback的解决或拒绝的返回值作为一个新的承诺(除非返回值是个promise,在承诺链的承诺和值都被解决的情况下)。它还将通过notifycallback方法的返回值进行通知。promise 不能从notifyCallback方法得到解决或拒绝 。

catch(errorCallback);

promise.then(null, errorCallback) 的快捷方式。

finally(callback,notifyCallback);

允许你观察一个承诺的解决或拒绝,但这样做不能修改最后的值。这可用于promise不论是被解决或拒绝后释放资源或做一些清理。

链式承诺

因为调用本次promise的方法将会返回一个新的延生的promise,它很容易创建一个承诺链:

  promise = promise.then(function(result){  return  result+1;  });

当一个承诺解决另一个承诺(这将推迟其进一步的解决)可能创建一个任何长度的链。它可能在链中的任何处暂停/推迟承诺。这使得它可以像$http的响应拦截这类强大的API。

Kris Kowal’s Q和$q的不同

以下是两个主要的不同:

在Angular里,$q和$rootScope.Scope Scope模型的观察机制集成,这意味着更快的将解决/拒绝的结果传播到你的model和避免不必要的浏览器重新渲染(这将导致ui的闪烁)。

Q比$q有更多的特性,但这是以字节为代价的。$q是小版本的,但包含所有常见的异步任务所重要的功能。

依赖:$rootScope

使用:$q(resolver);

方法

defer();

创建一个deferred对象,它代表一个将在将来完成的任务。返回一个deferred的新实例。

reject(reason);

创建一个由指定的理由拒绝的承诺。在承诺链中,这个api将被用于承诺的拒绝。如果你正在处理一个承诺链的最后一个承诺,那么你不需要担心它。

reason:常数,消息,异常或一个对象表示拒绝原因。

返回一个已经根据拒绝原因解决了的承诺。

when(value);

将一个对象或者一个值或者一个第三方承诺包装进$q承诺。当你处理一个可能是承诺或可能不是承诺或承诺来自一个不可信的来源的对象。

value:值或者承诺。

返回一个承诺。

resolve(value);

when的别名,为了与ES6保持一致。

all(promises);

当所有承诺都得到解决后,在一个单一的承诺里集合多个被解决的承诺。

promises:承诺的数组或者哈希。

返回一个将被结合一个数组/哈希或者值解决的单一的承诺,每个值在相同索引/键的数组/哈希承诺对应相对承诺,如果有任何承诺被拒绝,这将导致承诺被以相同的拒绝值拒绝。

使用代码:

  (function () {
angular.module('Demo', [])
.controller('testCtrl', ["$q", testCtrl]);
function testCtrl($q) {
var fn = function (value) {
var defer = $q.defer();
if (value == "Hello") {
defer.resolve("Hello World");
} else {
defer.reject("hello world");
}
return defer.promise;
};
var promise = fn("Hello");
promise.then(function (v) {
console.log("resolved with " + v);
}, function (r) {
console.log("rejected with " + r);
});//Hello World
var anotherPromise = fn();
anotherPromise.then(function (v) {
console.log("resolved with " + v);
}, function (r) {
console.log("rejected with " + r);
});//hello world
}
}());

承诺

  (function () {
angular.module('Demo', [])
.controller('testCtrl', ["$q", testCtrl]);
function testCtrl($q) {
var fnA = function (value) {
var defer = $q.defer();
if (value == "Hello") {
defer.resolve("Hello World -- fnA");
} else {
defer.reject("hello world -- fnA");
}
return defer.promise;
};
var fnB = function (value) {
var defer = $q.defer();
if (value == "Hello") {
defer.resolve("Hello World -- fnB");
} else {
defer.reject("hello world -- fnB");
}
return defer.promise;
};
var promise = fnA("Hello");
promise.then(function (v) {
console.log("resolved with " + v);//Hello World -- fnA
return fnB();
}, function (r) {
console.log("rejected with " + r);
return fnB("Hello");
}).then(function (v) {
console.log("resolved with " + v);
}, function (r) {
console.log("rejected with " + r);//hello world -- fnB
})
}
}());

.when():

  (function () {
angular.module('Demo', [])
.controller('testCtrl', ["$q", testCtrl]);
function testCtrl($q) {
var obj = { value: "Hello World" };
$q.when(obj.value).then(function (v) {
console.log(v);// Hello World
obj = { text: "hello world" }
return $q.when(obj.text);
}).then(function (v) {
console.log(v);// hello world
})
}
}());

.all():

  (function () {
angular.module('Demo', [])
.controller('testCtrl', ["$q", testCtrl]);
function testCtrl($q) {
var fnA = function (value) {
var defer = $q.defer();
if (value == "Hello") {
defer.resolve("Hello World -- fnA");
} else {
defer.reject("hello world -- fnA");
}
return defer.promise;
};
var fnB = function (value) {
var defer = $q.defer();
if (value == "Hello") {
defer.resolve("Hello World -- fnB");
} else {
defer.reject("hello world -- fnB");
}
return defer.promise;
};
var promiseA = fnA("Hello").then(function (v) {
console.log("resolved with " + v);
return fnB();
}, function (r) {
console.log("rejected with " + r);
return fnB("Hello");
});
var promiseB = fnB().then(function (v) {
console.log("resolved with " + v);
}, function (r) {
console.log("rejected with " + r);
});
var promises = [promiseA, promiseB];
$q.all(promises);
/* result:
** resolved with Hello World -- fnA
** rejected with hello world -- fnB
*/
}
}());

关于$q,本兽目前的理解也就这些,用的话也是看情况着用,更多时候觉得它就像语法糖一般,只是省了N多嵌套,但不得不说这个语法糖让代码可读性和整洁性好了很多。$q更多的好处是在promise和deferred,创建个承诺,在后面需要的地方再回来解决这个承诺。同时也推荐一篇关于描述$q的文章,雪狼大叔写的,url是:http://www.ngnice.com/posts/126ee9cf6ddb68

AngularJs $q 承诺与延迟的更多相关文章

  1. Angular - - $q 承诺与延迟

    $q 一个帮助处理异步执行函数的服务.当他们做完处理时,使用它们的返回值(或异常). 受 Kris Kowa’s Q 的启发,这是一个实现promise/deferred对象的启用. $q的两种方式- ...

  2. angular的$q,defer,promise

    $q是Angular的一种内置服务,它可以使你异步地执行函数,并且当函数执行完成时它允许你使用函数的返回值(或异常). 官网:http://docs.angularjs.cn/api/ng/servi ...

  3. angularjs 缓存 $q

    <!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...

  4. 深入浅出HTTP协议(WEB开发和面试必备)

    1. 基础概念篇   a.简介 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web Consortium)和 ...

  5. 深入理解http/https协议

    深入理解HTTP协议(转) http协议学习系列 1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(Wo ...

  6. 转载和积累系列 - 深入理解HTTP协议

    深入理解HTTP协议 1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web C ...

  7. Linux常用命令(三)

    1.top 说明:即时显示 process 的动态 语法格式:top [-] [d delay] [q] [c] [S] [s] [i] [n] [b]基本参数:d : 改变显示的更新速度,或是在交谈 ...

  8. http协议学习系列

    深入理解HTTP协议(转)  http://www.blogjava.net/zjusuyong/articles/304788.html http协议学习系列   1. 基础概念篇 1.1 介绍 H ...

  9. 深入理解HTTP协议、HTTP协议原理分析【转】

    转自:http://blog.csdn.net/lmh12506/article/details/7794512 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 基础概念篇 ...

随机推荐

  1. [MetaHook] Quake FMOD player demo

    CFMOD.h #ifndef CFMOD_H #define CFMOD_H #include "qfmod.h" struct Sound_t { char *pszName; ...

  2. 数据字典生成工具之旅(4):NPOI操作EXECL

    这篇会介绍NPOI读写EXECL,读写EXECL的组件很多,可以使用微软自己的COM组件EXECL.exe读写,不过这种方式限制很大. 1:客户环境必须装Office(虽然现在机子上不装Office的 ...

  3. Scala入门之函数进阶

    /** * 函数式编程进阶: * 1,函数和变量一样作为Scala语言的一等公民,函数可以直接赋值给变量: * 2, 函数更长用的方式是匿名函数,定义的时候只需要说明输入参数的类型和函数体即可,不需要 ...

  4. HEU KMS Activator v11.1.0 Windows激活

    HEU KMS Activator基于MDL论坛的“KMS Server Emulator”,是一款KMS激活工具,为“知彼而知己”原创工具.主要适用于Windows以及Office的VL版本,无需联 ...

  5. Maven的生命周期和插件

    首先解释下maven build等 Maven build是这个插件让你自己去配置执行目标的.Maven clean 清除上一次Maven执行的结果Maven generate-sources会根据p ...

  6. 浅谈SEO翻倍提升网站流量

    本文是在简单了解并且熟悉SEO技术的基础上加上自己的总结归纳,对于SEO还是一个长期的工程不是一天就能一下优化排名第一.下面就是我对SEO的一些见解: 一.关键字选择 内容相关 搜索次数多,竞争小 主 ...

  7. SharedPreference写入-读取

    SharedPreference文件保存格式为xml文件. 一.SharedPreference写入 SharedPreferences sharedPreferences = context.get ...

  8. 链队列的C/C++实现

    #include <iostream> using namespace std; const int N = 10; typedef int ELEMTYPE; typedef struc ...

  9. Activity has leaked window that was originally added -界面退出时未关闭对话框异常 android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running? -

    退出Activity时弹出登录框,点击确定finish当前Activity,结果报了这个错,随后查找资料知道 原因: 是因为退出Activity时没有关闭弹出框,出现了这个错误 解决方法: 只需要在a ...

  10. 关于idea 修改jsp文件后不能生效

    打开server 的配置界面: 其中 修改on update Action 为 Redeploy On frame deactivation 为Update classes and resources