node.js - 警告 : Possible EventEmitter - Node warning when running `foundation new`

标签 node.js zurb-foundation

每次我在 CLI 中运行 foundation new 来启动新的 Foundation 项目时,我都会收到一长串 Node 警告:

(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:15500) Warning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit

Node 号始终不同,但警告和警告数量始终相同。我该如何解决这个问题?

显示这些警告后,其他一切似乎都运行良好并且项目已创建。我不确定我是否应该担心这些警告。

最佳答案

在一篇关于 EventEmitter memory leaks 的博客文章中找到了此 Material 但在这里发布详细信息,因此该答案不是仅链接的答案。我对 Material 本身不负任何责任,只是找到它并创建答案,以便 Stackoverflow 可以看到它。

在 Node.js 和 io.js 中,您最终会看到以下错误消息:

(node) warning: possible EventEmitter memory leak detected. 11 a listeners added. Use emitter.setMaxListeners() to increase limit.

什么时候会真正发生泄漏? 当您不断添加事件处理程序而不删除它们时,就会发生泄漏。当您多次使用单个发射器实例时,会发生这种特殊情况。让我们创建一个返回流中下一个值的函数:

function next(stream) {
  // if the stream has data buffered, return that
  {
    let data = stream.read()
    if (data) return Promise.resolve(data)
  }

  // if the stream has already ended, return nothing
  if (!data.readable) return Promise.resolve(null)

  // wait for data
  return new Promise(function (resolve, reject) {
    stream.once('readable', () => resolve(stream.read()))
    stream.on('error', reject)
    stream.on('end', resolve)
  })
}

每次在流上调用 next() 时,都会添加一个关于可读、错误和结束的处理程序。在第 11 次 next(stream) 调用时,您将收到错误消息:

( Node )警告:检测到可能的 EventEmitter 内存泄漏。 11添加了一个听众。使用emitter.setMaxListeners()来增加限制。

您不断添加错误和结束处理程序,但没有删除它们,即使数据已成功读取并且这些处理程序不再相关。

清理事件处理程序

清理处理程序的正确方法是确保在 Promise 解析后,添加净 0 个事件处理程序:

return new Promise(function (resolve, reject) {
  stream.on('readable', onreadable)
  stream.on('error', onerror)
  stream.on('end', cleanup)

  // define all functions in scope
  // so they can be referenced by cleanup and vice-versa
  function onreadable() {
    cleanup()
    resolve(stream.read())
  }

  function onerror(err) {
    cleanup()
    reject(err)
  }

  function cleanup() {
    // remove all event listeners created in this promise
    stream.removeListener('readable', onreadable)
    stream.removeListener('error', onerror)
    stream.removeListener('end', cleanup)
  }
})

使用此方法,不会有事件发射器泄漏,因为在每个 Promise 解析后,净更改事件处理程序为 0。

并发处理程序

如果您希望同一个发射器上有多个监听器怎么办?例如,您可能有很多函数监听同一个发射器:

doThis1(stream)
doThis2(stream)
doThis3(stream)
doThis4(stream)
doThis5(stream)
doThis6(stream)
doThis7(stream)
doThis8(stream)
doThis9(stream)
doThis10(stream)
doThis11(stream)
doThis12(stream)
doThis13(stream)

如果上面的所有函数都向数据事件添加处理程序,您将收到相同的泄漏错误消息,但您知道实际上并不存在泄漏。此时,您应该相应地设置最大监听器数量:

return new Promise(function (resolve, reject) {
  // increase the maximum number of listeners by 1
  // while this promise is in progress
  stream.setMaxListeners(stream.getMaxListeners() + 1)
  stream.on('readable', onreadable)
  stream.on('error', onerror)
  stream.on('end', cleanup)

  function onreadable() {
    cleanup()
    resolve(stream.read())
  }

  function onerror(err) {
    cleanup()
    reject(err)
  }

  function cleanup() {
    stream.removeListener('readable', onreadable)
    stream.removeListener('error', onerror)
    stream.removeListener('end', cleanup)
    // this promise is done, so we lower the maximum number of listeners
    stream.setMaxListeners(stream.getMaxListeners() - 1)
  }
})

这允许您确认限制并控制事件处理,同时允许 Node.js 在实际发生泄漏时打印错误消息。

帮助编写更好的代码!

如果你只是简单地.setMaxListener(0),那么你可能会在不知不觉中发生泄漏。如果您看到任何使用 .setMaxListeners(0) 的代码(尤其是开源代码),请发出拉取请求来修复它!不要走捷径!

关于node.js - 警告 : Possible EventEmitter - Node warning when running `foundation new` ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39254438/

相关文章:

zurb-foundation - 包括使用 Composer 的基础

javascript - 通过Chrome Extension内容脚本在iFrame中激活Zurb Foundation的Joyride

javascript - 错误 : require() of ES modules is not supported when importing node-fetch

node.js - Ubuntu 下增加最大连接数? (Tsung并发测试)

css - Zurb Foundation 4 中网格单元之间的间距

html - 一个站点可以有多个 SCSS 文件 [foundation]

ruby-on-rails - 为什么我在此 SASS 文件中出现未定义的 Foundation 变量错误?

javascript - meteor 不会更新 mongodb 中的数据

node.js - 为 NodeJS cookie header 设置 HttpOnly 属性

javascript - 在新终端中使用 child_process 启动 Node.js Express 服务器