2

how I can use async functions with event emitter, in other information sources saying: do not use async functions with event emitter.

I want basically to mix an async function with an event emitter, so that it resolves and event emitter show the messages.

The code is as follows:

server.on('published', async (packet, client) => { // event emitter with async function
  debug(`Received: ${packet.topic}`)

  switch (packet.topic) {
    case 'agent/connected':
    case 'agent/disconnected':
      debug(`Payload: ${packet.payload}`)
      break
    case 'agent/message':
      debug(`Payload: ${packet.payload}`)

      const payload = parsePayload(packet.payload)

      if (payload) {
        payload.agent.connected = true

        let agent
        try {
          agent = await Agent.createOrUpdate(payload.agent)
        } catch (e) {
          return handleError(e)
        }
        debug(`Agent ${agent.uuid} saved`)

        // Notify Agent is Connected
        if (!clients.get(client.id)) {
          clients.set(client.id, agent)
          server.publish({
            topic: 'agent/connected',
            payload: JSON.stringify({
              agent: {
                uuid: agent.uuid,
                name: agent.name,
                hostname: agent.hostname,
                pid: agent.pid,
                connected: agent.connected
              }
            })
          })
        }

        // Store Metrics
        for (let metric of payload.metrics) {
          let m

          try {
            m = await Metric.create(agent.uuid, metric)
          } catch (e) {
            return handleError(e)
          }

          debug(`Metric ${m.id} saved on agent ${agent.uuid}`)
        }
      }
      break
  }
})

I want to apologize if this question is already done somewhere. I new in nodejs and I've found nothing about similar.

A similar question in title NodeJS 7: EventEmitter + await/async but it has nothing to do with this question.

  • does the code work? if not, describe the problem you are having, as "it doesn't work" is not a vlaid problem description – Jaromanda X Dec 13 '17 at 03:39
  • "*in other information sources saying*" - where does it say that, can you please link those? Also, why don't you believe them? – Bergi Dec 13 '17 at 06:05
  • Yes, you can use `async` functions as callbacks anywhere. However, the event emitter will not gain anything from this, it'll just throw the returned promises away. – Bergi Dec 13 '17 at 06:19
  • 1
    @JaromandaX No, my code doesn't not work, basically mi question that bears with this thread https://github.com/mcollina/mosca/issues/711 and not understand the answer. – Juan Diego Silva Dec 13 '17 at 12:24

1 Answers1

-1

The main problem of using async functions in event emmiter - is that you cannot handle resulting promise rejection. So you can do something like this:

const asyncEventHandler = async function(...args) { /* do anything here */ };
const eventHandlerWrapper = function(...args) {
  const promise = asyncEventHandler(...args);
  promise.catch(function(error) {
    // handle error here
  });
};

emitter.on("some-event", eventHandlerWrapper);

On the other hand - with sync function, you know, that listeners will call in sequence (next one starts when previous ends). With async listeners next listener will start right after first await in current listener. And there is nothing you can do with this.

Gheljenor
  • 362
  • 3
  • 3
  • 2
    No, that's not a problem with `async` functions specifically. *All* emitter callbacks must not throw, you just have to handle all errors. Whether you do that with a wrapper function or with `try`/`catch` inside the function itself doesn't make a difference. – Bergi Dec 13 '17 at 07:32