express里面有个util模块,这个模块主要的功能是将callback形式的异步api转换成promise形式的.
作用:原本需要通过传入回调函数来实现,但是现在可以用promise.then的方式来调用
promisify是个函数,参数也是函数,返回值也是函数
const { promisify } = require('util')
const fs = require('fs')
const reader = promisify(fs.readFile)
reader('./ww.txt', { encoding: 'utf-8' }).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
})
内部实现方式
const promisify = (fn) => {
return (...args) => {
return new Promise((resolve, reject) => {
fn(...args, (err, data) => {
if (err) reject(err)
resolve(data)
})
})
}
}
const demo = promisify((a, b, c, cb) => {
console.log(a, b, c)
cb(null, a)
})
demo(1, 2, 3).then((res) => {
console.log(res, 'res')
})
这是一个高阶函数柯里化,首先解释一下,因为在node中异步回调有一个约定:Error first , 也就是回调函数中的第一个参数一定要是Error对象,其余参数才是正确的数据,所以实现起来很简单,在匹配到第一个参数有值,也就是有error的话触发reject否则触发resolve
- promisify返回一个匿名函数,匿名函数接受原函数的参数
- 匿名函数被调用后根据这些参数来调用真实的函数,同时拼接一个用来处理结果的回调函数callback
- 监测到err有值,触发reject,其他情况触发resolve
注意:resolve只能传入一个参数,所以callback中没有必要使用...arg获取所有返回值
...args只是为了将参数类数组转换成真正的数组
如果赋值给其他变量,那么this指向可能会出问题,所以一般使用箭头函数,或者bind绑定对应的 this