首页 > 解决方案 > node.js util.promisify 是如何工作的?如何将 cb 样式转换为 promise 样式?

问题描述

我有以下练习:

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 的?

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

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))
})

标签: node.jspromisees6-promise

解决方案


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

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);
});

展平

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.log调用的原因。console.error错误处理更好地分离,并且与承诺不同。


推荐阅读