【问题标题】:bluebird Promise.promisifyAll can work while promisify a function of that object failsbluebird Promise.promisifyAll 可以在 promisify 该对象的功能失败时工作
【发布时间】:2019-04-04 04:55:11
【问题描述】:

我尝试承诺SFTPWrapper 并解决这个问题。我不确定它是否发生在其他物体上。

所以如果我只是promisify 一个 SFTPWrapper 函数,比如readdir,那么蓝鸟将拥有unhandledRejection : "Cannot read property 'readdir' of undefined" error。我试过util.promisify,同样的错误。

但是如果 promisifyAll(SFTPWrapper) 并且它按预期工作。但这是为什么呢?

----更新-----

我使用的代码,

var Client = require('ssh2').Client
var conn = new Client()
conn.on('ready', function() {
    conn.sftp(async function(err, sftp) {
        if (err) throw err
        try {
          // promisify will have Cannot read property 'readdir' of undefined error
          // both bluebird and util have the error

          //let readdirAsync = Promise.promisify(sftp.readdir)
          let readdirAsync = util.promisify(sftp.readdir)
          list = await readdirAsync(remotePathToList)

         // Promise.promisifyAll(sftp) work
         const sftp2 = Promise.promisifyAll(sftp)
         let list = await sftp2.readdirAsync(toRead)

【问题讨论】:

  • 您必须准确地向我们展示您正在使用的哪些 promisify 代码对我们没有帮助,以进一步帮助您。请展示 promisify 操作和 promisified 函数使用的实际代码。一般来说,关于代码的问题需要包含您遇到问题的实际代码(至少这是确保我们可以快速帮助您而无需大量其他问题的最佳方式)。
  • 您好,我已经展示了代码,其实很简单。

标签: node.js promise es6-promise bluebird


【解决方案1】:

您没有准确显示错误“无法读取未定义错误的属性'readdir'”的确切位置。如果出现在这行代码:

let readdirAsync = util.promisify(sftp.readdir);

那么,问题在于sftpundefined。但是,这似乎并不是问题所在,因为您说const sftp2 = Promise.promisifyAll(sftp) 确实有效。

所以,我猜当您尝试使用readdirAsync 时会出现问题。如果是这种情况,那么可能是因为您在执行let readdirAsync = util.promisify(sftp.readdir) 时丢失了 sftp 父级,这对 readdir 方法的实现很重要。如果确实如此,那么您可以这样做:

let readdirAsync = util.promisify(sftp.readdir).bind(sftp);

确保父对象保持绑定到方法。因为 Bluebird 的 .promisifyAll() 将新方法放在原始对象上,并且您将它们作为对象上的方法而不是普通函数调用,所以当您将它们称为 sftp2.readdirAsync() 时,与原始对象的绑定会自动发生。你也可以这样做:

sftp.readdirAsync = util.promisify(sftp.readdir);

然后,您可以调用sftp.readdirAsync(...).then(...).catch(...),它们将适当地绑定到sftp 对象。

附:在异步回调中使用if (err) throw err 从来都不是很好的错误处理。从字面上看,您永远不应该在异步回调中编写该行代码,除非该异步回调的调用者具有该异常的显式处理程序(通常不是这种情况)。它所做的只是将异常抛出到异步遗忘中,而没有机会在代码中的其他任何地方进行实际的错误处理。

【讨论】:

  • 就是你说的!! util.promisify(sftp.readdir).bind(sftp) 或 sftp.readdirAsync 解决问题!谢谢!!!
  • @Qiulang - 当宿主方法需要引用this(它的父对象)来完成它的工作时,就会发生这种情况。有时是这样(如sftp 示例中的情况,有时不是fs 模块中的情况。这完全取决于方法本身的实现以及它是否使用本地实例数据。
  • OK 所以这不是 SFTPWrapper 或 promisify 的错误,只是使用 promisify 时要小心的一个情况。再次感谢。它已经困扰我好几天了!
  • @Qiulang - 是的,只是一个通用的 Javascript 问题,它对需要它的宿主对象实例数据的方法进行外部引用。这就是.bind() 的用途。见this within ES6 class methodmethod doesn't work when passed to another function
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-09
  • 1970-01-01
相关资源
最近更新 更多