异步IO与同步IO在时间表现上,异步IO预期于最慢一个IO,而同步IO则是所有IO的总和。但是异步IO的结果也是需要统一处理的。因此就涉及到多异步之间的协作。
在node中,我们在全局上设置一个哨兵变量来协作。
下面代码使用process.nextTick来模拟一次异步的IO:
"use strict";
process.nextTick(function(){
console.log('nextTick的执行');
done();//每次调用count自增1
});
process.nextTick(function(){
console.log('nextTick的执行');
done();//每次调用count自增1
});
process.nextTick(function(){
console.log('nextTick的执行');
done();//每次调用count自增1
});
var count=0;//哨兵变量
var done=function(){
count++;
if(count===3){//当count为3的时候,说明三个异步都完成了,执行异步完成的处理
console.log('全部异步IO完成');
}
}
如果有多个方法需要处理异步的结果,我们可以增加多一个函数。由于哨兵变量是全局的,因此我们不需要再增加一个哨兵变量:
"use strict";
process.nextTick(function(){
console.log('nextTick的执行');
done();
done2();
});
process.nextTick(function(){
console.log('nextTick的执行');
done();
done2();
});
process.nextTick(function(){
console.log('nextTick的执行');
done();
done2();
});
var count=0;
var done=function(){
count++;
if(count===3){
console.log('done1:全部异步IO完成');
}
}
var done2=function(){
if(count===3){
console.log('done2:全部异步IO完成');
}
}
随着业务增长,如果done的数量越来越多,则可以使用事件发布/订阅来实现。这种方法在深入浅出node中有提到过:
"use strict";
const events = require('events');
var emitter=new events.EventEmitter();
process.nextTick(function(){
console.log('nextTick的执行');
emitter.emit("done");
});
process.nextTick(function(){
console.log('nextTick的执行');
emitter.emit("done");
});
process.nextTick(function(){
console.log('nextTick的执行');
emitter.emit("done");
});
var count=0;
var done=function(){
count++;
if(count===3){
console.log('done1:全部异步IO完成');
}
}
var done2=function(){
if(count===3){
console.log('done2:全部异步IO完成');
}
}
emitter.on('done',done);
emitter.on('done',done2);
可以看到,使用了emitter之后,我们不需要在每个异步中加入done、done2等等等,直接使用emitter.emit('done')便可。