Promise.delay (sleep) 和 Promise.timeout #11
Replies: 9 comments
-
想问一下,您在这里提到的 polyfill 会阻塞主线程的问题是什么意思?我没能复现出来(至少在 Node 和 Firefox 里): const timeout = async (f, ms, ...args) => {
const start = Date.now()
while (start + ms >= Date.now()) await Promise.resolve(0)
return f(...args)
}
console.log(1)
timeout(() => console.log(2), 4096)
console.log(3)
timeout(() => console.log(4), 10)
console.log(5) 输出的是正常的 1 3 5 4 2,延时也是对的。 P.S. 您好像不小心把 |
Beta Was this translation helpful? Give feedback.
-
你在执行以上代码之后立刻执行 1+1,会发现控制台无响应,直到 4 秒后才有反应。因为这个本质上和同步的 busy loop 区别不大。 |
Beta Was this translation helpful? Give feedback.
-
控制台没反应是因为 Promise.then 走的是 microtask。纯用 es 没法做出一个 macrotask 来,只能靠 setTimeout setInterval setImmediate 这些 HTML 规范里的东西;而在执行完所有 microtask 之前甚至不会更新 UI,更别提控制台了。所以,如果所有逻辑都只有 es 里的东西,就不会有 macrotask(更不会有 UI 卡死),只有 microtask,就不会卡死主线程。 和同步版本区别还是挺大的: const timeout = (f, ms, ...args) => {
const start = Date.now()
while (start + ms >= Date.now()) /* empty */;
return f(...args)
}
console.log(1)
timeout(() => console.log(2), 4096)
console.log(3)
timeout(() => console.log(4), 10)
console.log(5) 会出 12345 而不是正确的 13542。 |
Beta Was this translation helpful? Give feedback.
-
我觉得 Promise.delay/sleep 挺好的,就是历史上 setTimeout 都是 platform API,不知道 tc39 的人是否愿意把这个类似的能力放进 js 标准。 Promise.timeout 有个问题是本质上我们需要的是 cancellation。我们大概率希望能用 |
Beta Was this translation helpful? Give feedback.
-
可以看我在原帖之下的评论: |
Beta Was this translation helpful? Give feedback.
-
WICG: https://discourse.wicg.io/t/promise-delay-sleep-and-promise-timeout/4644 |
Beta Was this translation helpful? Give feedback.
-
我看了下原贴,我前面的观点和 kriskowal 的观点是一致的。我认为最好在 JS 语言里指定(虽然我们要克服一定的阻力)而不是扔给 WICG ——你要到 w3c 去进行标准化,而且 node.js 等其他 JS 环境也还是没有。setTimeout的差异已经是一个例证(虽然在实践上我们不care它们的差别,但语义上的微妙差别总是很讨厌),这个东西和cancellation一样最好在JS里标准化。理想上最好是node.js的人来champion 😝 |
Beta Was this translation helpful? Give feedback.
-
但现在的问题是 JS 里就是没有这个东西
没有 clock,没有 marco task,怎么在 JS 里指定它的语义呢?
这样也许能行,但你不觉得它很奇怪吗? |
Beta Was this translation helpful? Give feedback.
-
我和kriskowal的意思一致,不要依赖 setTimeout 而是反过来,如果定义了 delay,那么 setTimeout 反而能用 delay 来定义。 当然,问题就是得往JS里加某种东西(它不叫 setTimeout 而是某种更基本的东西),虽然看起来有点怪,但也不是说全然没有先例,比如 SharedArrayWorker 所依赖的 shared memory 语义背后的 agent,是 shared workers 在 JS 里的抽象;我们也可以定义某种类似的语言级抽象。 最主要的挑战还是在于谁有能力去推动这个东西…… (PS. ljharb说JS没有io,但如果 timer 被认为是 io,那么 Math.random() 也应该是某种 io) |
Beta Was this translation helpful? Give feedback.
-
Related
https://es.discourse.group/t/sleep-function/295/11await Promise.delay(2000)
也发在了
https://es.discourse.group/t/promise-delay-sleep-and-promise-timeout/349WICG https://discourse.wicg.io/t/promise-delay-sleep-and-promise-timeout/4644
有人有兴趣么🤔
Beta Was this translation helpful? Give feedback.
All reactions