深入浅析Node中的util.promisify()函数

广告:宝塔Linux面板高效运维的服务器管理软件 点击【 https://www.bt.cn/p/uNLv1L 】立即购买

深入浅析Node中的util.promisify()函数

Node.js 内置的 util 包有一个 promisify() 函数,可以将基于回调的函数转换为基于 Promise 的函数。本文就来给大家介绍一下Node.js 中的 util.promisify() 函数,希望对大家有所帮助。

让你可以使用 Promise 链式 和 async/await 与基于回调的 API。

例如,Node.js 的 fs 包 使用回调。通常,读取文件需要使用回调方式:

const fs = require('fs');fs.readFile('./package.json', function callback(err, buf) {    const obj = JSON.parse(buf.toString('utf8'));    obj.name; // 'masteringjs.io'});
登录后复制

你可以使用 util.promisify()fs.readFile() 函数转换为返回 Promise 的函数。【相关教程推荐:nodejs视频教程、编程教学】

const fs = require('fs');const util = require('util');// 将 `fs.readFile()` 转换为一个函数,该函数接受相同的参数但返回一个 Promiseconst readFile = util.promisify(fs.readFile);// 现在可以对 `readFile()` 使用 `await` 了!const buf = await readFile('./package.json');const obj = JSON.parse(buf.toString('utf8'));obj.name; // 'masteringjs.io'
登录后复制简单实现

util.promisify() 在内部是如何工作的?npm 上有一个 polyfill,你可以 在这里阅读完整的实现。你也可以 在这里找到 Node.js 的实现,不过出于教育目的,polyfill 更容易阅读。

util.promisify() 的核心思想是 在你传递的参数基础上添加了一个回调函数。这个回调函数解析(resolve)或拒绝(rejected) promisified 函数返回的 Promise。

有点啰嗦了,以下是 util.promisify() 方法一个简化的实现版本。

const fs = require('fs');// `util.promisify()` 的简化实现。不涵盖所有情况,不要在生产环境中使用!function promisify(fn) {    return function () {        const args = Array.prototype.slice.call(arguments);        return new Promise((resolve, reject) => {            fn.apply(this, [].concat(args).concat([(err, res) => {                if (err) {                    return reject(err);                }                resolve(res);            }]));        });    }}// 将 `fs.readFile()` 转换为一个函数,该函数接受相同的参数但返回一个 Promiseconst readFile = util.promisify(fs.readFile);// 现在可以对 `readFile()` 使用 `await` 了!const buf = await readFile('./package.json');const obj = JSON.parse(buf.toString('utf8'));obj.name; // 'masteringjs.io'
登录后复制

怎么理解?首先,util.promisify() 会向你传递的参数添加 1 个额外参数,然后使用这些新参数调用原始函数。那么底层函数就要支持这些数量的参数调用,举例:如果你正在使用类型为 [String,Object] 的 2 个参数调用 promisified 函数 myFn(),请确保原始函数支持调用签名 [String, Object, Function]

其次,util.promisify() 对于 函数上下文 有影响。

丢失上下文

丢失上下文(Losing Context) 表示调用函数时内部 this 值不正确 。丢失上下文是转换后的函数的常见问题:

class MyClass {  myCallbackFn(cb) {    cb(null, this);  }}const obj = new MyClass();const promisified = require('util').promisify(obj.myCallbackFn);const context = await promisified();context; // 打印 `undefined` 而非 `MyClass` 实例!
登录后复制

this 表示函数被调用时所属的对象。因此,你可以通过将 promisified 函数设置为同一对象的属性来保留上下文:

class MyClass {  myCallbackFn(cb) {    cb(null, this);  }}const obj = new MyClass();// 保留上下文,因为 `promisified` 是 `obj` 的一个属性obj.promisified = require('util').promisify(obj.myCallbackFn);const context = await obj.promisified();context === obj; // true
登录后复制

更多node相关知识,请访问:nodejs 教程!

以上就是深入浅析Node中的util.promisify()函数的详细内容,更多请关注9543建站博客其它相关文章!

广告:SSL证书一年128.66元起,点击购买~~~

9543建站博客
一个专注于网站开发、微信开发的技术类纯净博客。
作者头像
admin创始人

肥猫,知名SEO博客站长,14年SEO经验。

上一篇:html怎么加视频
下一篇:聊聊uniapp项目中怎么使用Axios

发表评论

关闭广告
关闭广告