深入浅出node.js第4章异步编程摘录

4.1函数式编程

4.2异步编程的优势与难点

4.2.1 优势

node带来的最大特性莫过于基于事件驱动的非阻塞I/O模型,这是他的灵魂所在。
在第3章中,我们讨论过node实现异步I/O的原理。利用事件循环的方式,js线程就像一个分配任务和处理结果的大管家,io线程池里的各个io线程都是小二,负责完成分配来的任务,小二与管家互不依赖,所以可以保持整体的高效率。缺点是管家无法承担过多的细节性任务,如果承担太多,则会影响到任务的调度,管家忙个不停,小二却得不到活干,结局是整体效率的降低。

4.2.2 难点

难点1:异常处理

try{
    process.nextTick(cb);
}catch(e){
//todo...
}

尝试对异步方法进行try/catch操作只能捕获当次事件循环内的异常,对cb执行时抛出的异常无能为力。
node在处理异常上形成了一种约定,将异常作为回调函数的第一个实参传回,如果是空值,则表明异步调用没有异常抛出。
另一个容易犯的错误是对用户传递的回调函数进行异常捕获,示例代码如下:

try{
    req.body=JSON.parse(buf,options.revier);
    callback();
}catch(err){
    err.body=buf;
    err.status=400;
    callback(err);
}

上述代码中,如果回调函数中出现异常,那么进入catch代码中执行,于是回调函数被执行了2次。正常的应该是:

try{
    req.body=JSON.parse(buf,options.revier);
}catch(err){
    err.status=400;
    return callback(err);
}
callback();

在编写异步方法时,只要将异常正确地传递给用户的回调函数即可,无需过多处理。

4.3 异步编程解决方案

4.3.1 事件发布/订阅模式

node自身提供的events模块是对发布/订阅模式的一个简单实现。
node对事件发布/订阅的机制做了一些额外的处理。

侦听器超过10个,警告。Use emitter.setMaxListeners() to increase limit
如果触发了error事件,EventEmitter会检查是否对error事件添加过侦听器。如果添加了,交给侦听器处理,否则作为异常抛出。如果外部没有捕获这个异常,将会Error [ERR_UNHANDLED_ERROR]: Unhandled error,引起线程退出。一个健壮的EventEmitter实例应该对error事件做处理。

1、继承events模块
node提供的核心模块中,有近半都继承了EventEmitter
2、雪崩

 const events = require('events');
class MyEmitter extends events {}
let proxy=new MyEmitter();
proxy.setMaxListeners(0);
let status='ready';
let select =function (cb) {
    proxy.once('selected',cb);
    if(status=='ready'){
        status='pending';
        setTimeout(function () {
            console.log('执行了。。。。');
            proxy.emit('selected','xxxxx');
            status='ready';
        },100)
    }
};
for(let i=0;i<100;i++){
    select(function () {
        console.log('.....')
    });
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值