Come funziona "await promisify (setTimeout) (ms)" quando manca il callback?

Aug 19 2020

Per una semplice funzione di sospensione asincrona in JavaScript, await promisify(setTimeout)(ms)funziona!

Ma come? Gli argomenti sembrano sbagliati.

  • promisify passa un callback di errore, quindi il
  • La chiamata setTimeout sarebbesetTimeout(ms, errorCallback)

che non dovrebbe funzionare, eppure funziona. Come?


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

Sfondo: await setTimeout(() => {}, 1000) non funziona . Questa battuta : await new Promise(resolve => setTimeout(resolve, 1000))non ha funzionato per me (perché?). Possiamo promisify manualmente : const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); await sleep(1000), ma che è una funzione aggiuntiva . Possiamo fare di meglio.

Risposte

1 snak Aug 20 2020 at 00:31

Questo perché ora setTimeoutha una funzione promessa personalizzata . Puoi trovarlo quando stampi setTimeout.

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

Le funzioni comuni che accettano una richiamata non nel modo standard possono avere una funzione promessa personalizzata e la util.promisifyrestituiscono quando una funzione ha una funzione promessa personalizzata.

PatrickFisher Aug 20 2020 at 00:39

setTimeoutè un caso speciale per promisify.

Secondo le specifiche di node.js :

Nota: questo metodo ha una variante personalizzata per le promesse che è disponibile utilizzando 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.
});

Con async / await, diventa:

await promisify(setTimeout)(1000)