【问题标题】:how does node.js util.promisify work? how to transform a cb style into a promise style with it?node.js util.promisify 是如何工作的?如何将 cb 样式转换为 promise 样式?
【发布时间】:2021-08-25 15:27:14
【问题描述】:

我有以下练习:

const { promisify } = require('util')

const print = (err, contents) => { 
  if (err) console.error(err)
  else console.log(contents) 
}

const opA = (cb) => {
  setTimeout(() => {
    cb(null,'A')
  }, 500)
}

const opB = (cb) => {
  setTimeout(() => {
    cb(null, 'B')
  }, 250)
}

const opC = (cb) => {
  setTimeout(() => {
    cb(null, 'C')
  }, 125)
}

在不修改函数和cb的情况下,是否可以使用promisify将其转换为基于promise的?

更新。我尝试了这个解决方案,但它没有按我的预期工作。打印顺序是 C B A,而我期待的是 A B C

const promA = promisify(opA)
const promB = promisify(opB)
const promC = promisify(opC)
promA(print).then(promB(print)).then(promC(print))

更新二。已解决,谢谢大家:

const promiseA = promisify(opA);
const promiseB = promisify(opB);
const promiseC = promisify(opC);
 
Promise.all([promiseA(),promiseB(),promiseC()]).then((res)=>{
  res.map(val => print(null,val))
})

【问题讨论】:

  • 是的,这是可能的。你试过了吗?
  • 如果你想知道它是如何工作的,你可以看看implementation,或者如果你想知道如何使用它阅读the docs。我不确定你所说的 “不修改 ... cb”是什么意思 - 如果你的意思是 printpromisifying 的意思是你不需要 回调了。
  • 据我所知,如果不更改部分练习代码,则无法使用 promisify。更改部分代码,而不是我可以轻松使用 promisify。也许我误解了练习的要求,但如果不是,我问:在不更改提供的代码的情况下,是否可以将其转换为基于 Promise 的?感谢您的耐心等待
  • 我认为我们对这里的一些翻译问题感到有些困惑,因此我们对“不更改提供的代码”有点失望。您是否不允许更改现有代码的任何,只需添加即可?什么可以碰,什么不能碰?
  • @ParentiDavide 您需要更改哪一部分?您能否请edit您的问题包括您将如何更改代码以使其工作(以您知道但不允许使用的方式)?

标签: node.js promise es6-promise


【解决方案1】:

我尝试了这个解决方案,但它没有像我预期的那样工作:

promA(print).then(promB(print)).then(promC(print))

在对函数进行承诺后,您不再应该传递回调 - 它是

promA().then(console.log, console.error);

为了对它们进行排序,请注意您仍然需要将函数传递给 .then(),而不是承诺 - 所以它是

promA().then(resA => {
    console.log(resA);
    return promB();
}).then(resB => {
    console.log(resB);
    return promC();
}).then(resC => {
    console.log(resC);
}).catch(err => {
    console.error(err);
});

flattened

promA().then(console.log).then(promB).then(console.log).then(promC).then(console.log).catch(console.error);

请注意print 函数及其(error, result) => void 签名仅适用于具有node.js 回调约定的异步函数,不适用于promise,这就是我在上面的示例中直接调用console.logconsole.error 的原因.错误处理更好地分离,并且与 promise 不同。

【讨论】:

    猜你喜欢
    • 2013-06-16
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    • 2016-12-09
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    相关资源
    最近更新 更多