写点什么

【Promise 源码学习】第十四篇 - 实现工具方法 promisify

作者:Brave
  • 2021 年 12 月 07 日
  • 本文字数:1244 字

    阅读完需:约 4 分钟

一,前言


上一篇,实现了 Promise 的两个静态 API:Promise.allSettledPromise.any,主要涉及以下几个点:


  • 测试原生 Promise.allSettled 的使用;

  • Promise.allSettled 的功能与特性分析;

  • Promise.allSettled 的源码实现、执行分析、功能测试;

  • 测试原生 Promise.any 的使用;

  • Promise.any 的功能与特性分析;

  • Promise.any 的源码实现、执行分析、功能测试;


本篇,实现一个 promisify 功能的工具函数;


二,promisify 介绍

1,什么是 promisify


promisify功能:如字面意思“promise 化”;

用于将异步回调 callback 形式的操作或 API 转换为 promise 形式;

2,promisify 的应用场景


目前主要用于 nodejs、小程序等场景

这些框架提供的 API 多为异步回调方式,比较容易形成编码中的“回调地狱”问题;


示例:nodejs 异步读取文件

const fs = require('fs') // 文件操作fs.readFile('test', 'utf8', function(err, data){  if(err) reject(err) // 错误优先原则  fs.readFile(data, 'utf8', function(err, data){   if(err) reject(err)   console.log(data);   // ...  })})
复制代码


在 nodejs 提供的 util 工具包中也存在一个 promisify 函数:

const fs = require('fs')const util = require('util')// 将原本 callback 形式的异步API readFile -> promise 化let readFile = util.promisify(fs.readFile);readFile('test', 'utf8').then((data)=>{  return readFile(data, 'utf8');}).then((data)=>{  console.log(data);}).catch(err =>{// ...})
复制代码


还提供了批量 promisify 操作:

let fs = require('fs');promisifyAll(fs); // 对 fs 库导出的对象整体 promisify;
fs.readFileAsync('test', 'utf8').then(data=>{ console.log(data);});
复制代码


备注:promisifyAll 对库导出的对象整体 promisify 操作后,新的方法命名规则一般为:原方法名+"Async"

避免了异步回调导致的多层嵌套问题,提升了代码的可读性;

下面就一起实现一个 promisify;


三,promisify 实现


  • 实现单一函数的 promise 化:

function promisify(fn) {  return function (...args) {    return new Promise((resolve, reject) => {      fn(...args, (err, data) => {        if (err) reject(err);        resolve(data);      })    })  }}
复制代码


这样,fn 就被进行了一次包装:将 callback 回调方式转为 promise 形式;


  • 批量 promise 化:

function promisifyAll(obj) {  // 将对象转为数组,遍历数组中的fn,依次完成 promisify 操作  Object.keys(obj).forEach(key => {    if (typeof obj[key] === 'function') {      obj[key + 'Async'] = promisify(obj[key])    }  })}
复制代码


备注:目前很多框架和库的 API 都有对 promise 的支持,所以使用时可以查阅文档,如果实在没有,可以使用以上 promisify 函数进行转化;如:可以使用 bluebird.js


四,结尾


本篇,实现一个 promisify 工具函数,主要涉及以下几个点:


  • promisify 简介和测试;

  • promisify 功能的实现:promisify、promisifyAll;


下一篇,介绍 generator 生成器;

用户头像

Brave

关注

还未添加个人签名 2018.12.13 加入

还未添加个人简介

评论

发布
暂无评论
【Promise 源码学习】第十四篇 - 实现工具方法 promisify