@by Ruth92(转载请注明出处)

第4章 异步编程

Node 能够迅速成功并流行起来的原因:

  • V8 和 异步 I/O 在性能上带来的提升;
  • 前后端 JavaScript 编程风格一致

一、函数式编程

  1. 高阶函数

    定义:是指把函数作为参数,或是将函数作为返回值的函数。

    应用:事件处理,数组的迭代和归并方法等。

  2. 偏函数用法

    偏函数用法:是指创建一个调用另外一个部分(参数或变量已经预置的函数)的函数的用法。

    偏函数:通过指定部分参数来产生一个新的定制函数的形式就是偏函数。

    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');

二、异步编程的优势与难点

  1. 优势

    最大特点:基于事件驱动的非阻塞 I/O 模型。可以使 CPU 与 I/O 并不相互依赖等待,让资源得到更好的利用。

    Node 实现异步 I/O 的原理:利用事件循环的调度方式,JavaScript 线程像一个分配任务和处理结果的大管家,I/O 线程池里的各个 I/O 线程都是小二,负责完成分配来的任务,小二与管家之间互不依赖,所以可以保持整体的高效率。

    事件循环模型的缺点:管家无法承担过多的细节性任务,否则,会影响任务的调度,从而降低整体效率。

  2. 难点

    • 难点1:异常处理;
    • 难点2:函数嵌套过深;
    • 难点3:阻塞代码;
    • 难点4:多线程编程;
    • 难点5:异步转同步

三、异步编程解决方案

  1. 事件发布/订阅模式

    即事件监听器模式,被广泛用于异步编程的模式,是回调函数的事件化。

    ps:其本身并无同步和异步调用问题,只不过在 Node 中多半是伴随事件循环而异步触发的。

     // 订阅:高阶函数的应用
    emitter.on('event1', function(message) {
    console.log(message);
    }); // 发布
    emitter.emit('event1', 'I am message!');

    事件发布/订阅模式可以实现一个事件与多个回调函数(事件侦听器)的关联。

  2. 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 对象,并将队列中余下的回调转交给它。

  3. 流程控制库

四、异步并发控制

《深入浅出Node.js》第4章 异步编程的更多相关文章

  1. 【读书笔记】《深入浅出nodejs》第四章 异步编程

    1. 异步编程的基础 -- 函数式编程 (1)高阶函数 -- 是可以把函数作为参数,或是将函数作为返回值的函数. (2)偏函数用法 -- 创建一个调用另外一个部分 -- 参数或变量已经预置的函数 -- ...

  2. 深入浅出Node.js(一):什么是Node.js

    Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹.从在github的访问量超过Rails,到去年底Node.jsS创始人Ryan Dalh加盟Joyent获得企业资助,再到 ...

  3. 深入浅出Node.js(一):什么是Node.js(转贴)

    以下内容转自:http://www.infoq.com/cn/articles/what-is-nodejs/ 作者:崔康 [编者按]:Node.js从2009年诞生至今,已经发展了两年有余,其成长的 ...

  4. 深入浅出Node.js(上)

    (一):什么是Node.js Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹.从在github的访问量超过Rails,到去年底Node.jsS创始人Ryan Dalh加盟 ...

  5. 《深入浅出Node.js》学习笔记(一)

    看了朴灵前辈的node.js系列文章,很开阔视野,虽然能力有限还是有很多不懂,但是还是希望能写下笔记,初步对node.js有点了解. 一.概念 Node.js不是JS应用.而是JS运行平台 Node. ...

  6. 《深入浅出Node.js》第7章 网络编程

    @by Ruth92(转载请注明出处) 第7章 网络编程 Node 只需要几行代码即可构建服务器,无需额外的容器. Node 提供了以下4个模块(适用于服务器端和客户端): net -> TCP ...

  7. 《深入浅出Node.js》第6章 理解 Buffer

    @by Ruth92(转载请注明出处) 第6章 理解 Buffer ✁ 为什么需要 Buffer? 在 Node 中,应用需要处理网络协议.操作数据库.处理图片.接收上传文件等,在网络流和文件的操作中 ...

  8. 一个月时间整理《深入浅出Node.js》

    今天终于把朴灵老师写的<深入浅出Node.js>给学习完了, 这本书不是一本简单的Node入门书籍,它没有停留在Node介绍或者框架.库的使用层面上,而是从不同的视角来揭示Node自己内在 ...

  9. 《深入浅出node.js(朴灵)》【PDF】下载

    <深入浅出node.js(朴灵)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062563 内容简介 <深入浅出Node. ...

随机推荐

  1. Jquery 复习练习(01)

    Jquery 复习练习 window.onload = function() {} == $(function() {}); 千万注意:js对象和jq对象的区别,这也是常常犯的错误 js对象举例: w ...

  2. [问题2014A12] 复旦高等代数 I(14级)每周一题(第十四教学周)

    [问题2014A12]  设 \(A,B\) 是 \(n\) 阶方阵且满足 \(AB=BA=0\), \(\mathrm{r}(A)=\mathrm{r}(A^2)\), 证明: \[\mathrm{ ...

  3. IntelliJ IDEA中使用综合使用Maven和Struts2

    在Intellij IDEA中手动使用Maven创建Web项目并引入Struts2 创建一个新的Maven项目 建好项目之后点击左下角的enable auto import 项目部署 在Moudule ...

  4. Codeforces Round #316 (Div. 2) D. Tree Requests dfs序

    D. Tree Requests time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  5. storm-kafka组件中KafkaOffsetMetric相关统计指标说明

    storm-kafka组件中KafkaOffsetMetric相关统计指标说明 storm-kafka是storm提供的一个读取kakfa的组件,用于从kafka队列中消费数据.KafkaOffset ...

  6. 深入浅出设计模式——模板方法模式(Template Method Pattern)

    模式动机 模板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一.在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中.在模板方法模式 ...

  7. 《BI项目笔记》创建标准维度、维度自定义层次结构

  8. Database,Uva1592

    Peter studies the theory of relational databases. Table in the relational database consists of value ...

  9. jQuery改变兄弟元素样式,及:not([class="allclassname"])筛选小结

    以前一直对于jquery感到很畏惧,最近做点击图表变色,将其他元素图片复位的小需求,总结了一下一点小心得. 主要两点是:1.将所有兄弟元素的样式设置为一样,对于子元素的遍历: 2.对于特殊不需要变化的 ...

  10. STM32学习笔记(十) CAN通讯测试(环回模式)

    1.CAN通讯的理解 想学习CAN通讯,那么要对通讯协议有一定的认知.通讯协议是指通信双方对数据传送控制的一种约定.约定中包括对数据格式,同步方式,传输速度,传送步骤,检纠错方式以及控制字符定义等问题 ...