Düğümün tam merkezinde yer alan programlama paradigmasının hızını ve verimliliğini kullanan başka bir çözüm sunmak istiyorum: olaylar.
Vaatler veya akış kontrolünü yönetmek için tasarlanmış modüller ile yapabileceğiniz her şey async, olaylar ve basit bir durum makinesi kullanılarak gerçekleştirilebilir; bu, belki de anlaşılması diğer seçeneklerden daha kolay olan bir metodoloji sunar.
Örneğin, birden çok dosyanın uzunluğunu paralel olarak toplamak istediğinizi varsayalım:
const EventEmitter = require('events').EventEmitter;
// simple event-driven state machine
const sm = new EventEmitter();
// running state
let context={
tasks: 0, // number of total tasks
active: 0, // number of active tasks
results: [] // task results
};
const next = (result) => { // must be called when each task chain completes
if(result) { // preserve result of task chain
context.results.push(result);
}
// decrement the number of running tasks
context.active -= 1;
// when all tasks complete, trigger done state
if(!context.active) {
sm.emit('done');
}
};
// operational states
// start state - initializes context
sm.on('start', (paths) => {
const len=paths.length;
console.log(`start: beginning processing of ${len} paths`);
context.tasks = len; // total number of tasks
context.active = len; // number of active tasks
sm.emit('forEachPath', paths); // go to next state
});
// start processing of each path
sm.on('forEachPath', (paths)=>{
console.log(`forEachPath: starting ${paths.length} process chains`);
paths.forEach((path) => sm.emit('readPath', path));
});
// read contents from path
sm.on('readPath', (path) => {
console.log(` readPath: ${path}`);
fs.readFile(path,(err,buf) => {
if(err) {
sm.emit('error',err);
return;
}
sm.emit('processContent', buf.toString(), path);
});
});
// compute length of path contents
sm.on('processContent', (str, path) => {
console.log(` processContent: ${path}`);
next(str.length);
});
// when processing is complete
sm.on('done', () => {
const total = context.results.reduce((sum,n) => sum + n);
console.log(`The total of ${context.tasks} files is ${total}`);
});
// error state
sm.on('error', (err) => { throw err; });
// ======================================================
// start processing - ok, let's go
// ======================================================
sm.emit('start', ['file1','file2','file3','file4']);
Hangi çıktı:
başlangıç: 4 yolun işlenmeye başlaması
forEachPath: 4 işlem zinciri başlatma
readPath: file1
readPath: file2
processContent: file1
readPath: file3
processContent: file2
processContent: file3
readPath: file4
processContent: file4
Toplam 4 dosya 4021
İşlem zinciri görevlerinin sırasının sistem yüküne bağlı olduğunu unutmayın.
Program akışını şu şekilde tasavvur edebilirsiniz:
start -> forEachPath - + -> readPath 1 -> processContent 1 - + -> done
+ -> readFile 2 -> processContent 2 - +
+ -> readFile 3 -> processContent 3 - +
+ -> readFile 4 -> processContent 4 - +
Yeniden kullanım için, çeşitli akış kontrol modellerini, yani seri, paralel, toplu iş, while, kadar vb. Desteklemek için bir modül oluşturmak önemsiz olacaktır.