我有一个公共事件发射器。
var events = require('events');
var eventEmitter = new events.EventEmitter();
发出诸如暂停,恢复,取消之类的事件。
我在我的函数中收听此事件。但是此函数在for循环内部调用。
let func = () =>{
//some Action runs async;
eventEmitter.on("pause",()=>{
//some action;
});
eventEmitter.on("resume",()=>{
//some action;
})
eventEmitter.on("cancel",()=>{
//some action;
})
return 0;
}
for(let i=0;i<anyNumber;i++){
func();
}
编辑:我真正的缩进是递归地读取目录中的文件并上传到s3 Bucket,因为没有官方的方法可以上传整个目录,因此我做到了。
上面提到的for循环实际上是fs.readdir,为简单起见,我将其称为for循环。
在func()中,我具有s3上传功能(分段上传),同时单击了暂停按钮,我需要暂停上传(这意味着已经保留了当前部分的上传,并停止了另一部分的上传。)
“恢复”表示继续部分上传,而“取消”表示我取消分段上传。
这是我的确切情况。
const readdirp = require('readdirp');
readdirp('.', {fileFilter: '*.js', alwaysStat: true})
.on('data', (entry) => {
const {path, stats: {size}} = entry;
s3Fileupload(path)
})
.on('warn', error => console.error('non-fatal error', error))
.on('error', error => console.error('fatal error', error))
.on('end', () => console.log('done'));
您现在可以帮我吗?
EDIT:1
let func = () =>{
let stream = es.map((data, next) => {
queue.defer(function(details, done) {
_this.s3MultiUpload(JSON.parse(details), options, done, details, next);
}, data);
}); }
let stream = readdirp(path)
stream.pipe(this.func());
可能是我在这里使用的d3Queue可能导致内存泄漏,我在读取目录时一直将函数推入整个过程?
答案 0 :(得分:1)
要删除侦听器,请致电eventEmitter.removeListener(event, listener)
。
您需要保留所有侦听器的副本。
另外,如果没有在其他地方使用发射器,则可以简单地调用eventEmitter.removeAllListeners()
。
如果我这样做,那之后我不能听那个事件了吗?
你是对的。您需要等待,直到不再需要该事件,然后将其删除。
理想情况下,您不想附加太多的侦听器。 无需增加限制,而是在单个事件回调中完成所有工作。
这是我要怎么做:
// Create an event emitter
const events = require('events');
const eventEmitter = new events.EventEmitter();
// Build a list of tasks to run
let tasks = [];
let tasksDone = 0;
for (let file of files) {
// Each task can be paused, resumed, canceled
let task = tasks.push({
pause: () => {/* TODO */},
resume: () => {/* TODO */},
cancel: () => {/* TODO */},
start: async () => {
// Do work
// Send a signal when task is done
eventEmitter.emit('done');
}
});
tasks.push(task);
}
// Store the listeners
let listeners = [
['pause', () => {
tasks.forEach(task => task.pause());
}],
['resume', () => {
tasks.forEach(task => task.resume());
}],
['cancel', () => {
tasks.forEach(task => task.cancel());
}],
['done', () => {
tasksDone++;
if (tasksDone === task.length) {
// All work done
// Remove listeners
listeners.forEach(([event, callback]) => {
eventEmitter.removeListener(event, callback);
});
}
}],
];
// Attach listeners
listeners.forEach(([event, callback]) => {
eventEmitter.on(event, callback);
});
// Start tasks
tasks.forEach(task => task.start());
尽管如此,您的应用程序可能由于其他原因而崩溃。 如果您同时打开太多文件或使用太多内存,则在完成任务之前,应用程序可能会崩溃。不用说,您还应该确保文件已关闭等。
我建议先对任务进行排队,然后一次完成一个任务。 如果需要更高的吞吐量,请编写一个调度程序以确保您一次不会消耗太多资源。
最后,对于节点程序,您可以连接Chrome调试器以找出为什么不释放内存的原因。如果问题仍然存在,您可以确切地找到导致内存中断的原因。