Как удалить источник событий из определенного узла функции js - PullRequest
0 голосов
/ 12 июля 2019

У меня есть общий источник событий.

var events = require('events');
var eventEmitter = new events.EventEmitter();

который генерирует такие события, как пауза, возобновление, отмена.

Я слушаю эти события в своей функции. но эта функция вызывается внутри для цикла.

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, для простоты я упомянул его как цикл.

в 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'));

теперь вы можете мне помочь?

РЕДАКТИРОВАТЬ: 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, который я использую здесь, может вызвать утечку памяти, я нажимаю на функцию полностью при чтении каталога?

1 Ответ

1 голос
/ 12 июля 2019

Чтобы удалить слушателя, позвоните 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, чтобы узнать, почему память не освобождается,Вы можете узнать, что именно удерживает память, если проблема не устранена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...