深入浅出Nodejs 4 异步编程

1. 函数编程

在js中, 函数是一等公民

高阶函数

把函数作为参数, 或者函数作为返回值

偏函数用法

var toString = Object.prototype.toString;
var isType = function(type){
	return = function(obj){
		return toString.call(obj) == '[object'+ type +']';
  }
}

2. 异步编程优势与难点

优势:

非阻塞I/O模型

在解决CPU密集型请求时, 建议CPU耗时不超过10ms, 或将大量的计算分解为诸多的小计算, 通过setImmediate()进行调度.

难点:

难点1

  1. 异常处理1; 异常处理try/catch的时候只能捕获js同步代码抛出的异常, 在事件循环中抛出的异常不会被捕获;

自行定义异步方法(封装node自带的异步函数), 需要遵循一些原则:

  1. 必须之心调用者传入的回调参数
  2. 正确传递异常传入回调函数

  3. 异常处理2:

    try{
     req.body = JSON.parse(buf, options.revier);
     callback();
    }catch(err){
     err.body = buf;
     err.status = 400;
     callback(err);
    }
    当异常抛出的时候, callbak会被执行两次;
    正确处理如下:
    try{
     req.body = JSON.parse(buf, options.revier);
    }catch(err){
     err.body = buf;
     err.status = 400;
     callback(err);
    }
    callback();
       
    

难点2:

函数嵌套过深(回调地狱)

难点3:

阻塞代码

如果需求需要实现sleep函数(node没有), 自行采用while实现则会占用CPU, 会破坏实现循环.

解决方法可以采用setTimeout()处理.

难点4:

多线程编程

可以使用cluster模块实现

难点5:

异步转同步

建议异步编程

3. 异步编程解决方案

时间发布/订阅模式

事件细节:

​ 一个事件添加超过10个侦听器, 将会得到一个警告. Emitter.setMaxListeners(0)可以去掉限制.

​ EventEmitter对象会检查error事件添加的侦听器, 存在错误会交给侦听器, 不存在将抛出异常.

  1. 继承events

    var events = require('events');
    function Stream(){
     events.EventEmitter.call(this);
    }
    util.inherits(Stream, events.EventEmitter)
    

node中的util模块封装了继承方法, 可以方便的继承EventEmtter类, 利用事件机制解决业务问题.

  1. 利用事件队列解决雪崩问题

    var status = "ready";
    var select = function(callback){
     if(status == "ready"){
    		status = "pending";
       db.select("SQL", function(results){
         status = "ready";
         callback(results);
       });
     }
    }
       
    
  2. 多异步之间的协作方案

  3. EventProxy的原理

Promise/Deferred模式

流程控制库

尾触发与Next

版本控制

Version Action Time
1.0 Init 2019-08-20