Daily-Question
Daily-Question copied to clipboard
【Q435】JS 如何实现一个 sleep/delay 函数
sleep
函数实现较为简单,也常作为对 Promise
的代码考察。在日常工作中,特别是 Node 写脚本时,常用它控制频率。
实现一个 sleep 函数格式如下:
type sleep = (s: number) => Promise<void>
追问:
实现一个 delay 函数格式如下,在 N 毫秒之后执行函数,并以函数结果作为返回值
function delay (func, seconds, ...args) {
}
// 在 3s 之后返回 hello, world
await delay((str) => str, 3000, 'hello, world')
// 在 3s 之后返回 hello, world,第一个函数可返回 promise
await delay((str) => Promise.resolve(str), 3000, 'hello, world')
function delay(time) {
return new Promise((resolve)=> {
setTimeout(() => {
resolve()
}, time)
})
}
const sleep = (t = 0) => new Promise(resolve => setTimeout(resolve, t));
const delay = <T extends (...args: any[]) => any>(
func: T,
seconds: number,
...args: Parameters<T>
): Promise<ReturnType<T>> => sleep(seconds).then(() => func(...args));
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
from: kurento-utils-js
sleep
函数既是面试中常问到的一道代码题,也是日常工作,特别是测试中常用的一个工具函数。
实现起来较为简单,一行即可实现,代码如下
const sleep = (seconds) => new Promise(resolve => setTimeout(resolve, seconds))
实现一个 delay 稍微复杂点,代码见 【Q435】JS 如何实现一个 sleep/delay 函数
function delay (func, seconds, ...args) {
return new Promise((resolve, reject) => {
setTimeout(() => {
Promise.resolve(func(...args)).then(resolve).catch(reject)
}, seconds)
})
}
使用代码测试:
console.log(new Date())
delay((str) => {
console.log(new Date())
return str
}, 3000, 'shanyue').then(o => console.log(o))
type resolving<P = any> = (res: P) => void
function delay<P extends any[], T extends (...args: P) => any = () => null>
(func: T, seconds: number = 0, ...args: P): Promise<ReturnType<T>> {
let _resolve: resolving<ReturnType<T>>
let _reject: resolving
setTimeout(() => {
try {
_resolve(func(...args))
} catch(e) {
_reject(e)
}
}, seconds)
return new Promise((resolve, reject) => {
_resolve = resolve
_reject = reject
})
}
@heretic-G 如果写成 TS 的话,如何标记 type
async function delay(func, second, ...args) {
return await new Promise(resolve => {
setTimeout(() => {
resolve(func(...args))
}, second)
})
}
delay(str => str, 3000, 'Hello world').then(res => {
console.log(res)
})
@HengistChan 如果 return promise 的话,应该可以不需要加 async/await
使用setTimeout有意义吗
实现一个 delay 稍微复杂点,代码见 【Q435】JS 如何实现一个 sleep/delay 函数
function delay (func, seconds, ...args) { return new Promise((resolve, reject) => { setTimeout(() => { Promise.resolve(func(...args)).then(resolve).catch(reject) }, seconds) }) }
@shfshanyue setTimeout 里应该需要 try/catch 一下 Promise.resolve().catch() 捕捉不到异常。