Вернуть данные асинхронно внутри emit

У меня есть фоновый процесс, написанный в node.js, который использует EventEmitter следующим образом:

var event = { returnValue: undefined };
eventEmitter.emit('name', event, argument);
return event.returnValue; // Example of doing things with event.returnValue.

Другой конец мероприятия:

eventEmitter.on('name', (event, argument) => {
    var returnValue = await asyncMethod(); // <- This method returns a Promise, so I could use await if possible or some other solution.
    event.returnValue = returnValue;
});

Я пытался найти элегантное решение для использования асинхронных методов, но, поскольку EventEmitter не поддерживает асинхронные функции вообще не могу использовать await в функции или что-то подобное. Одним из решений может быть установка returnValue на обещание, но это быстро становится непрактичным, особенно потому, что некоторые из моих функций повторяются через несколько асинхронных функций.

Мне нужно, чтобы весь код завершился правильно, прежде чем первый блок кода продолжится и попытается использовать event.returnValue.

Единственное мое решение - использовать стороннюю "синхронизацию", или никто в node.js не задумывался об этой проблеме?

Для меня нет никаких проблем, если поток заблокирован во время выполнения, поскольку это фоновый процесс без какого-либо графического интерфейса.

Не совсем понятно, что вы имеете в виду под One solution could be to set returnValue to a Promise, but that quickly becomes impractical, specially since some of my functions iterate through multiple asynchronous functions. и почему это проблема.

t.niese 26.08.2018 16:29

"Одним из решений может быть установка returnValue на обещание." - да, так и должно быть. Как вы думаете, почему это становится непрактичным? Вы можете привести пример этой «итерации через несколько асинхронных функций»?

Bergi 26.08.2018 16:29

@Bergi Код быстро становится загроможденным, если у меня есть несколько функций, возвращающих обещания, или повторение некоторого списка или массива, вызывающего асинхронную функцию внутри цикла.

einord 26.08.2018 16:39

@einord Вы имеете в виду, в обратном вызове одиночного события? Или вы говорите об установке нескольких прослушивателей событий? Если первое, вы можете тривиально построить единое обещание для всего, что делается с помощью цепочек then, синтаксиса async / await или Promise.all.

Bergi 26.08.2018 16:41

@Bergi, напишите ответ, показывающий это, если знаете простой способ :)

einord 26.08.2018 16:42

@einord Я просто знаю, что обещания - это простой способ, но я не могу привести конкретный пример нескольких функций, если я не знаю вашу точную проблему

Bergi 26.08.2018 16:45

@Bergi Проблема, когда вызывается несколько асинхронных функций, может выглядеть как его: { var items = []; item[0] = asyncMethod1();item[1] = asyncMethod2(); event.returnValue = items; /* <- This must be done in sync, since EventEmitter does not seem to support asynchronous code at all */ }

einord 26.08.2018 16:48

@einord event.returnValue = Promise.all(items), значит, это так.

Bergi 26.08.2018 16:51

@Bergi Отлично! Это работает для массивов. А как насчет более сложных объектов с большим количеством данных, часть из которых должна поступать из асинхронной функции? Пример: { var returnItem = { name: 'foo' }; returnItem.moreStuff = asyncMethod1(); event.ReturnValue = returnItem; }. Это сработает, но непрактично, поскольку любой код, пытающийся использовать returnItem, должен знать, что нужно ждать определенных значений.

einord 26.08.2018 17:09

@einord Promise.all(['foo', asyncMethod1(), …]).then(([name, moreStuff, …]) => ({name, moreStuff, …})) (или поместите сразу доступный материал в литерал объекта в обработчике then). Вы также можете использовать async / await для последовательного воспроизведения.

Bergi 26.08.2018 18:38

@Bergi - .then(() => {}) не вызывается асинхронно? Если так, я все еще не выбраюсь из "ада обратных вызовов", а также имею довольно запутанный код.

einord 26.08.2018 20:04

@einord Да, он создает объект, когда готовы все индивидуальные значения. Здесь нет ада обратных вызовов, он не гнездится бесконечно - обещания создают цепочку.

Bergi 26.08.2018 22:02
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
12
66
1

Ответы 1

Поскольку на самом деле, кажется, не существует никакого интуитивного способа дождаться синхронного разрешения Promise без обратных вызовов или использовать EventEmitter с асинхронными обратными вызовами, Я написал свой простой EventEmitter, содержащий массив, и настраиваемые методы on и emit.

Он правильно обрабатывает асинхронные функции, используемые в качестве параметров, поэтому я могу использовать его следующим образом:

asyncEmitter.on('name', async (event, argument) => {
    event.argument = await asyncMethod(); // Nice and clean code!
});

Конечно, я мог бы развить его дальше, создав функцию once и так далее, но на самом деле я полагаюсь только на on и emit. Интересно, почему команда узлов еще не решила эту проблему?

Другие вопросы по теме