$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. Android -- 桌面悬浮,QQ管家火箭实现

    续上一篇博客<Android -- 桌面悬浮,仿360>,传送门:http://www.cnblogs.com/yydcdut/p/3909888.html,在此代码上继续添加实现. 比起 ...

  2. 我在 CSDN 的小窝

    以后有文章,我会同时更新 博客园 和 CSDN. CSDN:http://blog.csdn.net/u010918003

  3. c++ this *this

    在一个类里每个成员函数都有一个this指针.this指针指向调用对象.如果方法需要引用整个调用 对象可以使用*this.this是对象的地址,而不是对象本身. *this是对象本身.可以将*this ...

  4. 一次由于开启 Safari 无痕浏览 引发的艰难“捉虫”事件

    事件回顾 做了一个移动端的页面,测试的时候出现了一个诡异的 bug.别的浏览器都好好的,就 ios 的 Safari 浏览器页面停止了渲染,似乎是有一段 js 文件没有载入.但是奇怪的是,同一型号的 ...

  5. Linux epoll 笔记(高并发事件处理机制)

    wiki: Epoll优点: Epoll工作流程: Epoll实现机制: epollevent; Epoll源码分析: Epoll接口: epoll_create; epoll_ctl; epoll_ ...

  6. 关于document.getElement获取元素返回值的问题

    获取网页元素有很多种方法,如下: document.all[];返回HTMLElement对象 document.all.tags[];返回NodeList对象,类似数组 document.getEl ...

  7. python作为一种胶水和c/c++

    如果需要用 Python 调用 C/C++ 编写的第三方库,只需要一个脚本语言来粘合它们.这个时候,用 Python ctypes 可以很方便地实现调用. StackOverflow 上的 Calli ...

  8. PHP之function_handling 函数

    function_handling 函数 function_handling 函数 需求: 编写一个函数,传入的参数个数不确定,请求出其和. 使用到 以下几个函数: 代码说明: 函数的参数可以是另外一 ...

  9. LAMP安装各种问题解决方案

    LAMP环境配置安装注意安装步骤及说明事项. LAMP安装各种问题解决 1. 访问ftp报错 解决: 关闭selinux vi /etc/selinux/config 内容修改为: selinux=d ...

  10. mvc4 ajax.beginform表单验证

    @{ Layout = null; } @model MvcApplication1.Models.User @using (Ajax.BeginForm("create", &q ...