代码之家  ›  专栏  ›  技术社区  ›  kpollock

nodejs:util.promisify,其中回调函数有多个参数

  •  0
  • kpollock  · 技术社区  · 6 年前

    我可能遗漏了一些非常明显的东西,但是我该如何使用 util.promisify 函数看起来像这样?

    function awkwardFunction (options, data, callback) {
        // do stuff ...
        let item = "stuff message"
        return callback(null, response, item)
    }
    

    我可以这样称呼它:

     awkwardFunction ({doIt: true},'some data', (err, result, item) => {
          console.log('result')
          console.log(result)
          console.log('item')
          console.log(item)
          done()
        })
    

    然后回来

    result
    { data: 'some data' }
    item
    stuff message
    

    使用已确认的版本时:

    let kptest = require('util').promisify(awkwardFunction)
    kptest({doIt: true},'some data')
       .then((response, item) => {
        console.log('response')
        console.log(response)
        console.log('item')
        console.log(item)
    
     })
     .catch(err => {
         console.log(err)
      })
    

    试图访问“response”和“item”,似乎忽略了第二个参数…

    result
    { data: 'some data' }
    item
    undefined
    

    有没有一种方法可以在不改变函数的情况下做到这一点(实际上,它是一个库函数,所以我不能)。

    4 回复  |  直到 6 年前
        1
  •  2
  •   Yury Tarabanko    6 年前

    不可能有 .then((response, item) => { 因为承诺代表着单一的价值。但是你可以这样吃 .then(({response, item}) => { 有两个字段的对象。

    您需要为函数提供一个自定义的promisify实现。

    const { promisify } = require('util')
    
    awkwardFunction[promisify.custom] = (options, data) => new Promise((resolve, reject) => {
      awkwardFunction(options, data, (err, response, item) => {
        if(err) { reject(err) }
        else { resolve({ response, item }) }
      })
    })
    
    const kptest = promisify(awkwardFunction)
    

    或者,如果这是唯一一个实现函数的地方,那么您可以直接使用该实现版本。 const kptest = (options, data) => new Promise(... 无其他确认步骤。

        2
  •  2
  •   Alex G    6 年前

    您可以自己做一个Promisify,返回一个用回调的参数解决的承诺,然后在随后的块上销毁它们。希望这有帮助。

    function awkwardFunction (options, data, callback) {
        // do stuff ...
        let item = "stuff message";
        return callback(null, data, item);
    }
    
    const mypromisify = (fn) =>
        (...args) =>
            new Promise(resolve =>
                fn(...args,
                    (...a) => resolve(a)
                )
            );
    
    const kptest = mypromisify(awkwardFunction);
    
    kptest({ doIt: true }, 'some data')
        .then(([error, response, item]) => {
            console.log(response);
            console.log(item);
        })
        .catch(err => {
            console.log(err);
        });
        3
  •  2
  •   Estus Flask    6 年前

    util.promisify 用于节点样式回调 function (err, result): void 签名。

    可以手动处理多个参数:

    let kptest = require('util').promisify(
      (options, data, cb) => awkwardFunction(
        options,
        data,
        (err, ...results) => cb(err, results)
      )
    )
    
    kptest({doIt: true},'some data')
    .then(([response, item]) => {...});
    

    如果需要更复杂的功能,一些第三方解决方案如 pify 可代替 允诺 ,它有 multiArgs option 来掩盖这个案子。

        4
  •  0
  •   kpollock    6 年前

    我无法决定我最喜欢哪种方法-所有3个答案都很好。尤里塔拉巴科的可能是最“标准”,亚历克斯G的是很好的通用性,和埃斯图斯的超级简单。

    我不想让这个问题“悬而未决”,因为这不是真的,对寻找相同信息的其他人来说也没有用处。

    如果有更好的方法来处理这个,请版主告诉我!