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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
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