NodeJS的异步、并发编程方案

一、事件发布/订阅模式(events)

事件发布/订阅模式自身并无同步和异步的问题,但在node中,emit()调用多半是伴随时间循环而异步触发的。
订阅:

emitter.on("event1", function(message){
	console.log(message);
});

发布

emitter.emit("event1","I am message")

注意事项:

  • 如果对一个事件添加了超过10个侦听器,将会得到一条警告。因为如果事件相关的监听器过多,可能会导致CPU占用过多。
  • 一个健壮的EventEmitter实例应该对error对象做处理

**雪崩问题:**在高访问量、大并发量的情况下缓存失效的场景,此时大量的请求同时涌入数据库中,数据库无法同时承受如此大的查询请求,进而影响到网站整体的响应速度。

**解决方法:**引入事件队列

var proxy = new events.EventEmitter();
var status = "ready";
var select = function(callback){
	proxy.once("selected", callback);
	if (status === "ready"){
		status = "spending";
		db.select("SQL", function(results){
			status = "ready";
			callback(results);
		})
	}
}

这里我们利用了once()方法,将所有请求的回调都压入事件队列中,利用其执行一次就会将监听器移除的特点,保证每一次回调只会被执行一次。这样就保证了,对于相同的SQL语句,同一个查询开始到结束的过程永远只有一次。一旦查询结束,得到的结果可以被这些调用者共同使用。
另外,此处可能因为存在监听器躲过而引发警告,需要调用下边的代码移除警告

setMaxListeners(0)

**多异步之间的协作方案:**利用偏函数来处理哨兵变量和第三方函数的关系

var emitter = new events.Emitter();
var done = after(times, render);

// 多对多
emitter.on("done", done);
emitter.on("done", other);

var after = function(times, callback){
	var count = 0, results = {};
	return function (key, value) {
		results[key] = value;
		count ++;
		if (count === times){
			callback(results);
		}
	}
}

db.query(sql, function(err, data){
	emitter.emit("done", "data", data)
});
fs.readFile(template_path, "utf-8", function(err, template){
	emitter.emit("done", "template", template);
})

EventProxy的 应用

  • all()方法:当all()方法中订阅的多个事件都被触发后,才会执行侦听器。
var ep = new EventProxy();
ep.all("template", "data", function(template, data){
	// TODD
});
fs.readFile(template_path, "utf-8", function(err, template){
	ep.emit("template", template);
})
db.query(sql, function(err, 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值