简体   繁体   中英

Why is it that a listener to EventEmitter after a synchronous function is not executed while same works for Asynchronous function?

Asynchronous function

import { EventEmitter } from 'events'
import { readFile } from 'fs'
class FindRegex extends EventEmitter {
  constructor (regex) {
    super()
    this.regex = regex
    this.files = []
  }
  addFile (file) {
    this.files.push(file)
    return this
  }
  find () {
    for (const file of this.files) {
      readFile(file, 'utf8', (err, content) => {
        if (err) {
          return this.emit('error', err)
        }
        this.emit('fileread', file)
        const match = content.match(this.regex)
        if (match) {
          match.forEach(elem => this.emit('found', file, elem))
        }
      })
    }
  }
}

Consumption:

const findRegexInstance = new FindRegex(/hello \w+/)
findRegexInstance
  .addFile('fileA.txt')
  .addFile('fileB.json')
  .find()
  .on('found', (file, match) => console.log(`Matched "${match}" in file ${file}`))
  .on('error', err => console.error(`Error emitted ${err.message}`))

In the above example even though the find() is called first, the "Matched ... in file" will be printed.

But if the same fuction is rewritten to make it synchronous :

find () {
  for (const file of this.files) {
    let content
    try {
      content = readFileSync(file, 'utf8')
    } catch (err) {
      this.emit('error', err)
    }
    this.emit('fileread', file)
    const match = content.match(this.regex)
    if (match) {
      match.forEach(elem => this.emit('found', file, elem))
    }
  }
  return this
}

Consumption:

const findRegexSyncInstance = new FindRegexSync(/hello \w+/)
findRegexSyncInstance
  .addFile('fileA.txt')
  .addFile('fileB.json')
  // this listener is invoked
  .on('found', (file, match) => console.log(`[Before] Matched "${match}"`))
  .find()
  // this listener is never invoked
  .on('found', (file, match) => console.log(`[After] Matched "${match}"`))

It will not output "[After] Matched.." message.

I vaguely understand why it won't work in case of synchronous find() . But, what I don't understand is how is it guaranteed to always work in case of async find() ?

Oddly enough I figured out the reason while typing the question itself.

In case of synchronous function call, any listener that has been registered after sync Find() will naturally go unexecuted as the event was raised before listening happened.

But in case of Asynchronous Find() the finding of file , readFileSync etc happens asynchronously and anything that happens asynchronously is added to event queue which gets executed only after the current stack is empty.

However, what I still wonder is whether in case of sync find()- will the listener registered after async find() get called the second time that piece of code is executed?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM