Node中的util.promisify()方法的基本使用和实现

 更新时间:2023年07月17日 09:56:28   作者:爆燃的小牛  
众所周知,在JS中实现异步编程主要是通过以下几种方案,回调函数,观察者模式,Generator,Promise,async / await ,今天就和大家一起聊一下在node中的一个util.promisify()这个API的基本使用和基本实现

异步编程解决方案

我们知道,在JS中实现异步编程主要是通过以下几种方案:

  • 回调函数:也是在ES6之前用的最多的方式,缺点是容易造成callback hell,可读性很差
  • 观察者模式:在NodeJS中的很多模块都继承了EventEmitter模块, NodeJS 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列。所有这些产生事件的对象都是 events.EventEmitter 的实例。
  • Generator:ES6 新引入了 Generator 函数,可以通过 yield 关键字,把函数的执行流挂起,为改变执行流程提供了可能,从而为异步编程提供解决方案。
  • Promise方案:号称是异步编程的终极解决方案
  • async / await async是ES7引入的语法 ,也是属于Promise方案中的一种

今天就聊一下在node中的一个util.promisify()这个API的基本使用和基本实现。

promisify

promisify这个方法可以是一个高阶函数,接受一个函数作为入参,可以将原本考回调函数实现的异步编程转化为promis的方案。这也是node提供出来,可以将之前非promise的方法通过这个api转化成promise来处理

基本使用

以一个简单的读写文件的fs.readFilereadFileSync为例说明。我们知道fs.readFile是通过回调函数的方式来获取读到的文件内容。而fs.readFileSync是通过同步的方式读取到文件内容。我们就可以使用promisify这个函数,将fs.readFile转变成promise的方式

// const.js 被读取的文件
const str = 123
// index.js
const fs = require('fs')
const path = require('path')
const { promisify } = require('util')
// 同步的方式读取const.js
const data = fs.readFileSync(path.resolve(__dirname,  './const.js'))
console.log('readFileSync:', data.toString());
// 通过回调函数的方式获取const.js内容
fs.readFile(path.resolve(__dirname, './const.js'), (error, data) => {
  if (error) console.log('error', error);
  console.log('readFile', data.toString());
})
// 将fs.readFile转为promise的方式获取文件内容
const readFile = promisify(fs.readFile)
readFile(path.resolve(__dirname, './const.js'))
  .then(data => {
    console.log('promisify: ', data.toString())
  })

达到的效果也符合预期:

自己实现一个promisify

我们在这里也自己实现一个promisify函数,达到上面的效果。即将一个接受回调函数通过回调完成异步编程的方式改为promise的方式

我们分析分析,思路其实很简单, 原本的函数接受一系列的参数,最后一个参数是一个回调函数,一般在node中错误先行,最后一个参数即任务完成时的回调函数也接受两个参数一个是error一个是处理后得到最后结果的data。如果有error的话就reject没有就resolve返回promise结果即可,详细分析步骤如下:

  • 我们实现的xpromisify是一个高阶函数,即接受一个函数作为参数
  • 接受的这个函数也有可能接受参数,所以我们对这个函数进行升阶处理,才能让这个函数接受其他参数
  • 我们最后返回的一定是一个Promise实例
  • 我们可以将步骤2中这个函数接受的参数数组得到(比如上述例子中fs.readFile()函数接受的path.resolve(__dirname, './const.js')),再构造一个函数作为回调函数,作为完整的参数,使用apply的方式让在步骤一中接受的函数执行
  • 构造的回调函数中判断步函数完成是否有错误,如果有错误我们reject掉,如果没有错误的话就把这个dataresolve即可

完整的代码实现如下所示:

// x-promisify.js
// xPromisify 是一个高阶函数,会将接受的fn函数转为promise
const xPromisify = (fn) => {
  // 接受的fn函数也会接受其他参数,所以升阶处理,return 一个函数这样就可以接受其他参数了
  return wrapFn = (...args) => {
    // 最终返回的肯定是一个promise实例
    return new Promise((resolve, reject) => {
        // 接受参数中加一个回调函数reject/resolve 最后结果
        args.push((error, data) => {
          if (error) reject(error)
          resolve(data)
        })
      // 此时args参数中就包含的fn执行所需要的所有参数了
      fn.apply(null, args)
    })
  }
}
module.exports = {
  xPromisify
}

我们可以通过上述例子的fs.readFile这个函数来检查一下:

const { xPromisify } = require('./x-promisify')
const xReadFile = xPromisify(fs.readFile);
xReadFile(path.resolve(__dirname, './const.js'))
  .then(data => {
    console.log('data', data.toString())
  })

执行效果如下所示:

总结

其实我们做的事情只是将回调函数的逻辑做了修改,原本是直接在回调中处理业务逻辑,这里我们修改为在回调函数中把异步事件处理的结果通过reject / resove给返回出去 我们也可以看一下在NodeJS中对这一部分的实现:

到此这篇关于Node中的的util.promisify()方法的基本使用和实现的文章就介绍到这了,更多相关Node 的util.promisify()方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • koa-router路由参数和前端路由的结合详解

    koa-router路由参数和前端路由的结合详解

    这篇文章主要给大家介绍了关于koa-router路由参数和前端路由的结合的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用koa-router具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • 使用node.js实现微信小程序实时聊天功能

    使用node.js实现微信小程序实时聊天功能

    在微信这个聊天工具里的小程序上实现聊天功能,总觉得很诧异,今天小编给大家带来了使用node.js实现微信小程序实时聊天功能,感兴趣的朋友一起看看吧
    2018-08-08
  • nodejs如何在package.json中设置多条启动命令

    nodejs如何在package.json中设置多条启动命令

    这篇文章主要介绍了nodejs如何在package.json中设置多条启动命令,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • Node中的util.promisify()方法的基本使用和实现

    Node中的util.promisify()方法的基本使用和实现

    众所周知,在JS中实现异步编程主要是通过以下几种方案,回调函数,观察者模式,Generator,Promise,async / await ,今天就和大家一起聊一下在node中的一个util.promisify()这个API的基本使用和基本实现
    2023-07-07
  • Node.js 回调函数实例详解

    Node.js 回调函数实例详解

    这篇文章主要介绍了Node.js 回调函数实例详解的相关资料,需要的朋友可以参考下
    2017-07-07
  • Node.js中的cluster模块深入解读

    Node.js中的cluster模块深入解读

    NodeJS引入了Cluster模块试图简化这些体力劳动,使用Cluster模块可以运行并管理多个实例进程,下面这篇文章主要给大家介绍了关于Node.js中cluster模块的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧
    2018-06-06
  • Node.js 异步编程之 Callback介绍(一)

    Node.js 异步编程之 Callback介绍(一)

    这篇文章主要介绍了Node.js 异步编程之 Callback介绍(一),本文用实例讲解Callback的相关知识,本文是第一篇,下一篇小编会跟进,需要的朋友可以参考下
    2015-03-03
  • 快速掌握Node.js事件驱动模型

    快速掌握Node.js事件驱动模型

    这篇文章主要为大家详细介绍了Node.js事件驱动模型,首先了解一下传统的线程网络模型,然后再学习了解Node.js事件驱动模型,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • 在Node.js中设置响应的MIME类型的代码详解

    在Node.js中设置响应的MIME类型的代码详解

    在 Node.js 中设置响应的 MIME 类型是为了让浏览器正确解析服务器返回的内容,比如 HTML、CSS、图片、JSON 等,我们通常通过设置响应头中的 Content-Type 字段来完成,本文就给大家详细介绍了在Node.js中设置响应的MIME类型的方法,需要的朋友可以参考下
    2025-04-04
  • Node.js net模块的使用示例

    Node.js net模块的使用示例

    本文主要介绍了Node.js net模块的使用示例,net模块支持TCP通信,处理TCP连接和数据传输,具有一定的参考价值,感兴趣的可以了解一下
    2025-02-02

最新评论