《深入浅出Node.js》第4章 异步编程
@by Ruth92(转载请注明出处)
第4章 异步编程
Node 能够迅速成功并流行起来的原因:
- V8 和 异步 I/O 在性能上带来的提升;
- 前后端 JavaScript 编程风格一致
一、函数式编程
高阶函数
定义:是指把函数作为参数,或是将函数作为返回值的函数。
应用:事件处理,数组的迭代和归并方法等。
偏函数用法
偏函数用法:是指创建一个调用另外一个部分(参数或变量已经预置的函数)的函数的用法。
偏函数:通过指定部分参数来产生一个新的定制函数的形式就是偏函数。
var toString = Object.prototype.toString;
// 原来,可扩展性不高
var isString = function(obj) {
return toString.call(obj) == '[object String]';
}; var isFunction = function(obj) {
return toString.call(obj) == '[object Function]';
}; // 偏函数用法
var isType = function(type) {
return function(obj) {
return toString.call(obj) == '[object' + type + ']';
};
}; var isString = isType('String');
var isFunction = isType('Function');
二、异步编程的优势与难点
优势
最大特点:基于事件驱动的非阻塞 I/O 模型。可以使 CPU 与 I/O 并不相互依赖等待,让资源得到更好的利用。
Node 实现异步 I/O 的原理:利用事件循环的调度方式,JavaScript 线程像一个分配任务和处理结果的大管家,I/O 线程池里的各个 I/O 线程都是小二,负责完成分配来的任务,小二与管家之间互不依赖,所以可以保持整体的高效率。
事件循环模型的缺点:管家无法承担过多的细节性任务,否则,会影响任务的调度,从而降低整体效率。
难点
- 难点1:异常处理;
- 难点2:函数嵌套过深;
- 难点3:阻塞代码;
- 难点4:多线程编程;
- 难点5:异步转同步
三、异步编程解决方案
事件发布/订阅模式
即事件监听器模式,被广泛用于异步编程的模式,是回调函数的事件化。
ps:其本身并无同步和异步调用问题,只不过在 Node 中多半是伴随事件循环而异步触发的。
// 订阅:高阶函数的应用
emitter.on('event1', function(message) {
console.log(message);
}); // 发布
emitter.emit('event1', 'I am message!');
事件发布/订阅模式可以实现一个事件与多个回调函数(事件侦听器)的关联。
Promise/Deferred模式:包含 Promise 和 Deferred
☊ 使用事件的方式:执行流程需要被预先设定。
$.get('/api', {
success: onSuccess,
error: onError,
complete: onComplete
});
♤ Promist/Deferred:可以先执行异步调用,延迟传递处理。这样即使不调用
success()
、error()
等方法,Ajax 也会执行。$.get('/api')
.success(onSuccess)
.error(onError)
.complete(onComplete)
♧ 在原始的 API 中,一个事件只能处理一个回调,而通过 Defferred 对象,可以对事件加入任意的业务处理逻辑。
$.get('/api')
.success(onSuccess1)
.success(onSuccess2)
☛【Promises/A】
在 API 的定义上,一个 Promise 对象只要具备
then()
方法即可。要求如下:接受完成态、错误态的回调方法。在操作完成或出现错误时,将会调用对应方法。
可选地支持
progress
事件回调作为第三个方法。then()
方法只接受function
对象,其余对象将被忽略。then()
方法继续返回Promise
对象,以实现链式调用。then(fulfilledHandler, errorHandler, progressHandler)
☛【Promises 和 Deferred 的差别】
Deferred 主要是用于内部,用于维护异步模型的状态;Promise 则作用域外部,通过
then()
方法暴露给外部以添加自定义逻辑。与事件发布/订阅模式相比,Promise/Deferred 模式的 API 接口和抽象模型都十分简洁。它将业务中不可变的部分封装在了 Deferred 中,将可变的部分交给了 Promise。
Promise 是高级接口,事件是低级接口。低级接口可以构成更多复杂的场景,高级接口一旦定义,不太容易变化,不再有低级接口的灵活性,但对于解决典型问题非常有效。
☛【Promises 中的多异步协作】
all()
方法:将两个单独的 Promise 重新抽象组合成一个新的 Promise。只有所有异步操作成功,这个异步操作才算成功,否则有一个异步操作失败,整个异步操作就失败。
☛【Promises 的进阶知识】
要让 Promise 支持链式执行,主要通过以下两个步骤:
(1)将所有的回调都存到队列中;
(2)Promise 完成时,逐个执行回调,一旦检测到返回了新的 Promise 对象,停止执行,然后将当前 Deferre 对象的 promise 引用改变为新的 Promise 对象,并将队列中余下的回调转交给它。
流程控制库
四、异步并发控制
《深入浅出Node.js》第4章 异步编程的更多相关文章
- 【读书笔记】《深入浅出nodejs》第四章 异步编程
1. 异步编程的基础 -- 函数式编程 (1)高阶函数 -- 是可以把函数作为参数,或是将函数作为返回值的函数. (2)偏函数用法 -- 创建一个调用另外一个部分 -- 参数或变量已经预置的函数 -- ...
- 深入浅出Node.js(一):什么是Node.js
Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹.从在github的访问量超过Rails,到去年底Node.jsS创始人Ryan Dalh加盟Joyent获得企业资助,再到 ...
- 深入浅出Node.js(一):什么是Node.js(转贴)
以下内容转自:http://www.infoq.com/cn/articles/what-is-nodejs/ 作者:崔康 [编者按]:Node.js从2009年诞生至今,已经发展了两年有余,其成长的 ...
- 深入浅出Node.js(上)
(一):什么是Node.js Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹.从在github的访问量超过Rails,到去年底Node.jsS创始人Ryan Dalh加盟 ...
- 《深入浅出Node.js》学习笔记(一)
看了朴灵前辈的node.js系列文章,很开阔视野,虽然能力有限还是有很多不懂,但是还是希望能写下笔记,初步对node.js有点了解. 一.概念 Node.js不是JS应用.而是JS运行平台 Node. ...
- 《深入浅出Node.js》第7章 网络编程
@by Ruth92(转载请注明出处) 第7章 网络编程 Node 只需要几行代码即可构建服务器,无需额外的容器. Node 提供了以下4个模块(适用于服务器端和客户端): net -> TCP ...
- 《深入浅出Node.js》第6章 理解 Buffer
@by Ruth92(转载请注明出处) 第6章 理解 Buffer ✁ 为什么需要 Buffer? 在 Node 中,应用需要处理网络协议.操作数据库.处理图片.接收上传文件等,在网络流和文件的操作中 ...
- 一个月时间整理《深入浅出Node.js》
今天终于把朴灵老师写的<深入浅出Node.js>给学习完了, 这本书不是一本简单的Node入门书籍,它没有停留在Node介绍或者框架.库的使用层面上,而是从不同的视角来揭示Node自己内在 ...
- 《深入浅出node.js(朴灵)》【PDF】下载
<深入浅出node.js(朴灵)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062563 内容简介 <深入浅出Node. ...
随机推荐
- 9-this
第九课 this 一.this基本概念 this是Javascript语言的一个关键字.在JavaScript中,this是动态绑定,或称为运行期绑定的.在不同的情况下,this指向各不相同.但是有一 ...
- [问题2015S09] 复旦高等代数 II(14级)每周一题(第十教学周)
[问题2015S09] 设 \(A,B\) 是 \(n\) 阶复矩阵, 满足 \(\mathrm{rank}(AB-BA)\leq 1\), 证明: \(A,B\) 可同时上三角化. 问题解答请在以 ...
- C++实现树的基本操作,界面友好,操作方便,运行流畅,运用模板
Ⅰ.说明: .采用左孩子右兄弟的方式,转化为二叉树来实现. .树的后根遍历与二叉树的中根遍历即有联系又有区别,请读者注意分析体会. Ⅱ.功能: .创建树并写入数据 .先根遍历树 .计算树高 .后根遍历 ...
- 【转】对硬盘进行分区时,GPT和MBR区别。
在Windows 8或8.1中设置新磁盘时,系统会询问你是想要使用MBR还是GPT分区.GPT是一种新的标准,并在逐渐取代MBR. GPT带来了很多新特性,但MBR仍然拥有最好的兼容性.GPT并不是W ...
- Java设置环境变量的含义(JAVA_HOME,PATH,CLASSPATH)
开发Java程序之前,需要在计算机行安装并配置Java开发环境.一种是直接安装Myeclipse,利用其自带的JDK编译运行:另一种是在我们的Windows或者Linux平台下安装JDK,配置环境变量 ...
- openssl evp 哈希算法(md5,sha1,sha256)
1. 简述 openssl提供了丰富密码学工具,一些常用的哈希算法 比如md5,sha 可以直接用提供的md5.h ,sha.h 接口使用: 为了方便开发者使用,openssl 又提供了一个EVP, ...
- Ipad Safari iframe cookie 当浏览器默认禁用第三方COOKIE
前一阵子,我们发现高版本的Safari中默认会阻止第三方cookie,如下图所示. 问题 什么是第三方cookie呢?在访问一个网站A时,网站A算作第一方,如果网站A中引用了另一个网站X(网站X的域名 ...
- C++ | boost库 类的序列化
是的,这是今年的情人节,一篇还在研究怎么用的文章,文结的时候应该就用成功了. 恩,要有信心 神奇的分割线 不知何时装过boost库的header-only库, 所以ratslam中的boost是可以编 ...
- guava学习--事件驱动模型
转载:http://www.cnblogs.com/whitewolf/p/4132840.html http://www.cnblogs.com/peida/p/EventBus.html 更好 ...
- iPhone/iPad/Android UI尺寸规范
iPhone界面尺寸