An in-depth look at the promisify() method of the Node.js util module

青灯夜游
Release: 2021-09-06 10:16:13
forward
3122 people have browsed it

An in-depth look at the promisify() method of the Node.js util module

Node.jsThe built-inutilmodule has apromisify()method, This method converts a callback-based function into a Promise-based function. This allows you to use Promise chains andasync/awaitwith callback-based APIs.

For example, thefsmodule of Node.js needs to use a callback when reading a file:

const fs = require('fs') fs.readFile('./package.json', function callback(err, buf) { const obj = JSON.parse(buf.toString('utf8')) console.log(obj.name) // 'Example' -> package.json 包名 })
Copy after login

We can useutil.promisify()Convert the callback function offs.readFile()into a Promise-returning function:

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')) console.log(obj.name) // 'Example'
Copy after login

How does promisify work?

util.promisify()How does it work behind the scenes? There is apolyfillon npm and you can read thefull implementationhere. You can also find theNode.js implementationhere, but for ease of understanding, the polyfill is easier to read. [Recommended learning: "nodejs Tutorial"]

util.promisify()The key idea behind it isAdd a callback function to the incoming parameters. This callback function resolves or rejects the Promise returned by the promisified function.

For ease of understanding, the following is a very simplifiedutil.promisify()custom implementation example:

const fs = require('fs') // util.promisify() 的简化实现。不包括所有情况,不要在 prod 环境中使用此选项! 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 != null) { return reject(err) } resolve(res) }])) }) } } // 将 fs.readFile() 转换为一个接受相同参数但返回 Promise 的函数。 const readFile = promisify(fs.readFile) // 现在可以将 readFile() 与 await 一起使用! const buf = await readFile('./package.json') const obj = JSON.parse(buf.toString('utf8')) console.log(obj.name) // 'Example'
Copy after login

So what does this mean? First,util.promisify()adds 1 extra parameter to the passed in parameters and then calls the original function with these new parameters. This means that the underlying function needs to support that number of parameters. So if you are callingmyFn()a promisified function with 2 type parameters[String, Object], make sure the original function supports[String, Object, Function].

So what does this mean? First,util.promisify()adds an extra parameter to the passed in parameters, then calls the original function with these new parameters. This means that the underlying function needs to support that number of parameters. So if you call the promisified functionmyFn()with 2 arguments of type[String, Object], make sure the original function supports[String, Object, Function].

Secondly,util.promisify()has an impact on the function context (this).

Lost context

Lost context (this) means that the function call ended with the wrong value. Losing context is a common problem with cast functions:

class MyClass { myCallbackFn(cb) { cb(null, this) } } const obj = new MyClass() const promisified = require('util').promisify(obj.myCallbackFn) const context = await promisified() console.log(context) // 打印 undefined 而不是 MyClass 实例!
Copy after login

Remember thatthisis any object that contains properties when the function is called. 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() console.log(context === obj) // true
Copy after login

For more programming related knowledge, please visit:Programming Video! !

The above is the detailed content of An in-depth look at the promisify() method of the Node.js util module. 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
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!