util.promisify
History
promisify on a function that returns a Promise is deprecated.util.promisify(original): Function
Takes a function following the common error-first callback style, i.e. taking
an (err, value) => ... callback as the last argument, and returns a version
that returns promises.
import { promisify } from 'node:util'; import { stat } from 'node:fs'; const promisifiedStat = promisify(stat); promisifiedStat('.').then((stats) => { // Do something with `stats` }).catch((error) => { // Handle the error. });
const { promisify } = require('node:util'); const { stat } = require('node:fs'); const promisifiedStat = promisify(stat); promisifiedStat('.').then((stats) => { // Do something with `stats` }).catch((error) => { // Handle the error. });
Or, equivalently using async functions:
import { promisify } from 'node:util'; import { stat } from 'node:fs'; const promisifiedStat = promisify(stat); async function callStat() { const stats = await promisifiedStat('.'); console.log(`This directory is owned by ${stats.uid}`); } callStat();
const { promisify } = require('node:util'); const { stat } = require('node:fs'); const promisifiedStat = promisify(stat); async function callStat() { const stats = await promisifiedStat('.'); console.log(`This directory is owned by ${stats.uid}`); } callStat();
If there is an original[util.promisify.custom] property present, promisify
will return its value, see Custom promisified functions.
promisify() assumes that original is a function taking a callback as its
final argument in all cases. If original is not a function, promisify()
will throw an error. If original is a function but its last argument is not
an error-first callback, it will still be passed an error-first
callback as its last argument.
Using promisify() on class methods or other methods that use this may not
work as expected unless handled specially:
import { promisify } from 'node:util'; class Foo { constructor() { this.a = 42; } bar(callback) { callback(null, this.a); } } const foo = new Foo(); const naiveBar = promisify(foo.bar); // TypeError: Cannot read properties of undefined (reading 'a') // naiveBar().then(a => console.log(a)); naiveBar.call(foo).then((a) => console.log(a)); // '42' const bindBar = naiveBar.bind(foo); bindBar().then((a) => console.log(a)); // '42'
const { promisify } = require('node:util'); class Foo { constructor() { this.a = 42; } bar(callback) { callback(null, this.a); } } const foo = new Foo(); const naiveBar = promisify(foo.bar); // TypeError: Cannot read properties of undefined (reading 'a') // naiveBar().then(a => console.log(a)); naiveBar.call(foo).then((a) => console.log(a)); // '42' const bindBar = naiveBar.bind(foo); bindBar().then((a) => console.log(a)); // '42'
Using the util.promisify.custom symbol one can override the return value of
util.promisify():
import { promisify } from 'node:util'; function doSomething(foo, callback) { // ... } doSomething[promisify.custom] = (foo) => { return getPromiseSomehow(); }; const promisified = promisify(doSomething); console.log(promisified === doSomething[promisify.custom]); // prints 'true'
const { promisify } = require('node:util'); function doSomething(foo, callback) { // ... } doSomething[promisify.custom] = (foo) => { return getPromiseSomehow(); }; const promisified = promisify(doSomething); console.log(promisified === doSomething[promisify.custom]); // prints 'true'
This can be useful for cases where the original function does not follow the standard format of taking an error-first callback as the last argument.
For example, with a function that takes in
(foo, onSuccessCallback, onErrorCallback):
doSomething[util.promisify.custom] = (foo) => { return new Promise((resolve, reject) => { doSomething(foo, resolve, reject); }); };
If promisify.custom is defined but is not a function, promisify() will
throw an error.
util.promisify.custom
History
symbolIn addition to being accessible through util.promisify.custom, this
symbol is registered globally and can be
accessed in any environment as Symbol.for('nodejs.util.promisify.custom').
For example, with a function that takes in
(foo, onSuccessCallback, onErrorCallback):
const kCustomPromisifiedSymbol = Symbol.for('nodejs.util.promisify.custom'); doSomething[kCustomPromisifiedSymbol] = (foo) => { return new Promise((resolve, reject) => { doSomething(foo, resolve, reject); }); };