Как ждать, пока несколько экземпляров EventEmitter отправят одно и то же событие в Node.js?

1

Я работаю над модулем/утилитой Node.js, который позволит мне замаскировать некоторые каталоги/файлы. Короче говоря, сейчас у меня есть основная функция, которая выглядит примерно так:

util.scaffold("FileName")

Этот метод "scaffold" возвращает экземпляр EventEmitter, поэтому при использовании этого метода я могу сделать что-то вроде этого:

util.scaffold("Name")
.on("done", paths => console.log(paths)

Другими словами, когда все файлы будут созданы, событие "done" будет выпущено со всеми путями файловых лесов.

Все хорошо до сих пор.

Прямо сейчас я пытаюсь выполнить некоторые тесты и тесты с помощью этого метода, и я пытаюсь найти способ выполнить некоторые операции (утверждения, журналы и т.д.) После того, как этот метод "scaffold" был вызван несколько раз с помощью другое "имя". Например:

const names = ["Name1", "Name2", "Name3"] 
const emitters = names.map(name => {
return util.scaffold(name)
})

Если я возвращаю Promise вместо EventEmitter, я знаю, что могу сделать что-то вроде этого:

Promise.all(promises).then(()=> {
//perform assertions, logs, etc
})

Тем не менее, я не уверен, как я могу сделать эквивалент с помощью EventEmitters. Другими словами, мне нужно подождать, пока все эти эмиттеры не выберут это же событие (т.е. "Сделано"), а затем выполните другую операцию.

Любые идеи/предложения, как это сделать?

Заранее спасибо.

  • 1
    Не могли бы вы обернуть источники событий в обещания и использовать эти обещания в Promise.all ()?
  • 0
    Вы абсолютно правы, это было проще, чем я думал.
Теги:
eventemitter

3 ответа

1

Самый простой подход, как упоминалось другими, заключается в том, чтобы возвращать обещания вместо экземпляров EventEmitter. Однако в соответствии с вашим вопросом вы можете написать свой обратный вызов для done события следующим образом:

const names = ['Name1', 'Name2', 'Name3']
let count = 0
util.scaffold('Name').on('done', (paths) => {
  count += 1
  if (count < names.length) {
    // There is unfinished scaffolding
  } else {
    // All scaffolding complete
  }
})
1

С обещанием. У вас есть уникальная информация, когда "все" сделано. Конечно, это когда все обещания внутри заполнены или отвергнуты.

Если у вас есть EventEmitter, информация, когда "все" выполнена, не может быть сохранена внутри логики EventEmitter, потому что она не знает, где и как часто происходит повторное событие.

Поэтому первым решением было бы управлять внешним состоянием "все сделано", и когда это изменится на true, вы выполните другую операцию.

Так что, как и обещание. Вы должны обернуть его.

Второй подход, который я мог представить, - это завод, на котором вы создаете EventEmitters, который отслеживает экземпляры. Затем эта фабрика может предоставить информацию о том, были ли все экземпляры запущены. Но этот подход может потерпеть неудачу на многих уровнях: один Instance-> много вызовов; Один Instance-> нет вызова;...

только мои 5 центов и я были бы рады видеть другое решение

0

Я закончил тем, что предложил @theGleep и обернул каждый из этих эмитентов внутри Promise, например:

const names = ["Name1", "Name2", "Name3"] 
const promises = names.map(name => {
     return new Promise((resolve) => {
       util.scaffold(name).on("done", paths => {
       resolve(paths)})
  })
})

// and then

Promise.all(promises).then(result => {
    // more operations
})

Кажется, что я делаю то, что мне нужно, поэтому я просто буду использовать это сейчас. Спасибо всем за ваши отзывы :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню