Я работаю над модулем/утилитой 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. Другими словами, мне нужно подождать, пока все эти эмиттеры не выберут это же событие (т.е. "Сделано"), а затем выполните другую операцию.
Любые идеи/предложения, как это сделать?
Заранее спасибо.
Самый простой подход, как упоминалось другими, заключается в том, чтобы возвращать обещания вместо экземпляров 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
}
})
С обещанием. У вас есть уникальная информация, когда "все" сделано. Конечно, это когда все обещания внутри заполнены или отвергнуты.
Если у вас есть EventEmitter, информация, когда "все" выполнена, не может быть сохранена внутри логики EventEmitter, потому что она не знает, где и как часто происходит повторное событие.
Поэтому первым решением было бы управлять внешним состоянием "все сделано", и когда это изменится на true, вы выполните другую операцию.
Так что, как и обещание. Вы должны обернуть его.
Второй подход, который я мог представить, - это завод, на котором вы создаете EventEmitters, который отслеживает экземпляры. Затем эта фабрика может предоставить информацию о том, были ли все экземпляры запущены. Но этот подход может потерпеть неудачу на многих уровнях: один Instance-> много вызовов; Один Instance-> нет вызова;...
только мои 5 центов и я были бы рады видеть другое решение
Я закончил тем, что предложил @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
})
Кажется, что я делаю то, что мне нужно, поэтому я просто буду использовать это сейчас. Спасибо всем за ваши отзывы :)