Open CyanSalt opened 6 years ago
path: async-timer
const every = async function* (interval) { let resolve = null const id = setInterval(() => { resolve(id) }, interval) while (true) { yield await new Promise(r => resolve = r) } } ;(async () => { for await (const id of every(1000)) { if (tick > 9) { clearInterval(id) } } })()
break
clearInterval
const every = async function* (interval) { let resolve = null let count = 0 const id = setInterval(() => { if (resolve) { resolve(count++) resolve = null } else { clearInterval(id) } }, interval) while (!resolve) { yield await new Promise(r => resolve = r) } } ;(async () => { for await (const tick of every(1000)) { if (tick > 9) break } })()
setInterval
sleep
const sleep = timeout => new Promise(resolve => setTimeout(resolve, timeout)) const every = async function* (interval) { while (true) yield await sleep(interval) } ;(async () => { for await (const _ of every(1000)) { if (Math.random() > 0.5) break } })()
注意,目前的语法(ES2018)不支持箭头函数的异步生成器。
const after = async function* (executor) { while (true) { yield await new Promise(executor) } } ;(async () => { for await (const _ of after(r => r()))) { if (Math.random() > 0.9999) break } for await (const _ of after(requestAnimationFrame)) { if (Math.random() > 0.9999) break } for await (const _ of after(requestIdleCallback)) { if (Math.random() > 0.9999) break } })()
path: async-timer
break
作为clearInterval
的语义,于此同时返回值可以用来作为循环次数:setInterval
,代码可以更简便。下面的sleep
是一个很常用的异步 sleep 实现,缺点是如果循环耗时较多,实际时间不够精准注意,目前的语法(ES2018)不支持箭头函数的异步生成器。