Comment fonctionne `wait promisify (setTimeout) (ms)` lorsque le rappel est manquant?

Aug 19 2020

Pour une simple fonction de veille asynchrone en JavaScript, ça await promisify(setTimeout)(ms)marche!

Mais comment? Les arguments semblent faux.

  • promisify transmet un rappel d'erreur, de sorte que
  • L' appel setTimeout seraitsetTimeout(ms, errorCallback)

qui ne devrait pas fonctionner, mais cela fonctionne. Comment?


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

Contexte: await setTimeout(() => {}, 1000) ne fonctionne pas . Ce one-liner : await new Promise(resolve => setTimeout(resolve, 1000))n'a pas fonctionné pour moi (pourquoi?). Nous pouvons promisify manuellement : const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); await sleep(1000), mais qui est une fonction supplémentaire . On peut faire mieux.

Réponses

1 snak Aug 20 2020 at 00:31

C'est parce qu'il setTimeouta maintenant une fonction promise personnalisée . Vous pouvez le trouver lorsque vous imprimez setTimeout.

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

Les fonctions courantes qui acceptent un rappel qui ne sont pas de la manière standard peuvent avoir une fonction promise personnalisée et la util.promisifyretournent lorsqu'une fonction a une fonction promise personnalisée.

PatrickFisher Aug 20 2020 at 00:39

setTimeoutest un cas particulier pour promisify.

Selon les spécifications de node.js :

Remarque: Cette méthode a une variante personnalisée pour les promesses qui est disponible en utilisant 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.
});

Avec async / await, cela devient:

await promisify(setTimeout)(1000)