`` await promisify (setTimeout) (ms) `ทำงานอย่างไรเมื่อการโทรกลับหายไป

Aug 19 2020

สำหรับฟังก์ชัน async sleep ที่เรียบง่ายใน 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))ไม่ทำงานสำหรับฉัน (ทำไม?) เราสามารถpromisify ด้วยตนเอง : const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); await sleep(1000)แต่ที่เป็นฟังก์ชั่นพิเศษ เราทำได้ดีกว่านี้

คำตอบ

1 snak Aug 20 2020 at 00:31

เนื่องจากsetTimeoutมีฟังก์ชันสัญญาที่กำหนดเองในขณะนี้ setTimeoutคุณสามารถค้นหาได้เมื่อคุณพิมพ์

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

ฟังก์ชันทั่วไปที่ใช้การโทรกลับไม่เป็นไปตามมาตรฐานอาจมีฟังก์ชัน Promisified ที่กำหนดเองและutil.promisifyส่งกลับเมื่อฟังก์ชันมีฟังก์ชันสัญญาที่กำหนดเอง

PatrickFisher Aug 20 2020 at 00:39

setTimeoutเป็นกรณีพิเศษสำหรับpromisify.

ตามข้อกำหนด node.js :

หมายเหตุ: วิธีนี้มีตัวแปรที่กำหนดเองสำหรับสัญญาที่พร้อมใช้งานโดยใช้ 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)