1

对于 JavaScript 中的简单异步睡眠功能,await promisify(setTimeout)(ms)可以!

但是怎么做?论据看起来是错误的。

  • promisify传递一个错误回调,所以
  • setTimeout调用将是setTimeout(ms, errorCallback)

这不应该工作,但它确实有效。如何?


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

背景:await setTimeout(() => {}, 1000) 不起作用。这个单线await new Promise(resolve => setTimeout(resolve, 1000))对我不起作用(为什么?)。我们可以手动承诺它const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); await sleep(1000),但这是一个额外的功能。我们可以做得更好。

4

2 回答 2

2

这是因为setTimeout现在有一个自定义的承诺功能。您可以在打印时找到它setTimeout

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

不以标准方式接受回调的普通函数可能具有自定义的承诺函数,并util.promisify在函数具有自定义的承诺函数时返回它。

于 2020-08-20T00:31:12.657 回答
1

setTimeout是 的一个特例promisify

根据node.js 规范

注意:这个方法有一个自定义的 promises 变体,可以使用 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.
});

使用 async/await,就变成了:

await promisify(setTimeout)(1000)
于 2020-08-20T00:39:03.897 回答