Home > Web Front-end > JS Tutorial > An in-depth analysis of the util.promisify() function in Node

An in-depth analysis of the util.promisify() function in Node

青灯夜游
Release: 2023-04-12 17:56:15
forward
1442 people have browsed it

The built-in util package of Node.js has a promisify() function that can convert callback-based functions into Promise-based functions. This article will introduce you to the util.promisify() function in Node.js. I hope it will be helpful to you.

An in-depth analysis of the util.promisify() function in Node

Allows you to use Promise chaining and async/await with callback-based APIs.

For example, Node.js's fs package uses callbacks. Usually, reading a file requires the use of a callback:

const fs = require('fs');
fs.readFile('./package.json', function callback(err, buf) {
    const obj = JSON.parse(buf.toString('utf8'));
    obj.name; // 'masteringjs.io'
});
Copy after login

You can use util.promisify() to convert the fs.readFile() function into a function that returns a Promise . [Related tutorial recommendations: nodejs video tutorial, Programming teaching]

const fs = require('fs');
const util = require('util');

// 将 `fs.readFile()` 转换为一个函数,该函数接受相同的参数但返回一个 Promise
const readFile = util.promisify(fs.readFile);

// 现在可以对 `readFile()` 使用 `await` 了!
const buf = await readFile('./package.json');

const obj = JSON.parse(buf.toString('utf8'));
obj.name; // 'masteringjs.io'
Copy after login

Simple implementation

util.promisify() How does it work internally? There is a polyfill available on npm and you can read the full implementation here. You can also find the Node.js implementation here, but for educational purposes the polyfill is easier to read.

util.promisify() The core idea is to add a callback function based on the parameters you pass. This callback function resolves or rejects the Promise returned by the promisified function.

It’s a bit verbose, the following is a simplified implementation version of the

util.promisify() method.

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()` 转换为一个函数,该函数接受相同的参数但返回一个 Promise
const readFile = util.promisify(fs.readFile);

// 现在可以对 `readFile()` 使用 `await` 了!
const buf = await readFile('./package.json');

const obj = JSON.parse(buf.toString('utf8'));
obj.name; // 'masteringjs.io'
Copy after login

How to understand? First,

util.promisify() will add 1 extra parameter to the parameters you passed, and then call the original function with these new parameters. Then the underlying function must support these number of parameter calls. For example: if you are calling the promisified function myFn() with 2 parameters of type [String, Object], please make sure Primitive functions support the calling signature [String, Object, Function].

Secondly,

util.promisify() has an impact on function context.

Losing Context

Losing Context Indicates that the internal this value is incorrect when the function is called. Losing context is a common problem with transformed functions:

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` 实例!
Copy after login

this represents the object the function was called on. Therefore, you can preserve the context by setting the promisified function to a property of the same object:

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
Copy after login
For more node-related knowledge, please visit:

nodejs tutorial!

The above is the detailed content of An in-depth analysis of the util.promisify() function in Node. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:juejin.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template