简体   繁体   中英

How does `await promisify(setTimeout)(ms)` work when the callback is missing?

For a simple async sleep function in JavaScript, await promisify(setTimeout)(ms) works!

But how? The arguments look wrong.

  • promisify passes an error callback, so the
  • setTimeout call would be setTimeout(ms, errorCallback)

which should not work, yet it does. How?


import { promisify } from 'util'
(async () => {
  // const start = Date.now()
  await promisify(setTimeout)(1000)
  // console.log(Date.now() - start)
})()
node <<HEREDOC
  (async () => {
    // const start = Date.now();
    await require('util').promisify(setTimeout)(1000);
    // console.log(Date.now() - start);
  })()
HEREDOC

Background: await setTimeout(() => {}, 1000) doesn't work . This one-liner : await new Promise(resolve => setTimeout(resolve, 1000)) did not work for me (why?). We can promisify it manually : const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); await sleep(1000) const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); await sleep(1000) , but that is an extra function . We can do better.

This is because setTimeout has a custom promisified function now. You can find it when you print setTimeout .

> console.log(setTimeout)
{ [Function: setTimeout] [Symbol(util.promisify.custom)]: [Function] }
undefined

Common functions that take a callback not in the standard way may have a custom promisified function, and util.promisify returns it when a function has a custom promisified function.

setTimeout is a special case for promisify .

Per the node.js specs :

Note: This method has a custom variant for promises that is available using util.promisify()

 const util = require('util'); const setTimeoutPromise = util.promisify(setTimeout); setTimeoutPromise(40, 'foobar').then((value) => { // value === 'foobar' (passing values is optional) // This is executed after about 40 milliseconds. });

With async/await, that becomes:

await promisify(setTimeout)(1000)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM