用例
将一个使用回调函数实现异步操作的方法Promisify后,可以使用.then来管理回调
function timer(timeout, callback) {
setTimeout(callback, timeout)
} // 延迟指定的时间后调用 callback 函数
// 回调方式使用
timer(1000, () => { console.log('after 1000ms') })
// promisify方式使用
const newTimer = promisify(timer)
newTimer(1000)
.then(() => { console.log('after 1000ms') })
实现
首先,由用例可知,需要把要转换的函数的最后一个参数 callback 独立出去, 同时 promisify 返回一个新的函数,这个函数不需要 callback 参数
因此,这个 callback 需要我们自己实现,它的作用是让 newTimer 返回的Promise状态变更为 resolved,从而触发 then 中的函数
function promisify(fn) {
return function (...args) {
return new Promise((resolve) => {
// 异步函数完成任务执行 callback 时,该 Promise 即 resolved
fn(...args, resolve)
})
}
}
结语
promisify之后,可以更清晰阅读、管理复杂的回调嵌套问题
假设请求b需要请求a中的数据才能正确发出:
fetchData(urlA, res => {
// handle data then fetch another url
fetchData(urlB + '?res=' + res, res => {
console.log(res)
})
})
promisify之后:
const promisedFetch = promisify(fetchData)
promisedFetch(urlA).then(res => {
return promisedFetch(urlB + '?res=' + res)
}).then(res => {
console.log(res)
})
这样更易于阅读和维护