Appearance
2821. 延迟每个 Promise 对象的解析
ts
type Fn = () => Promise<any>
const delayAll = (functions, ms) => {
return functions.map(
(fn) => () =>
new Promise((resolve, reject) =>
setTimeout(() => {
fn().then(resolve).catch(reject)
}, ms)
)
)
}延迟的语义
这里的要求是:每个函数返回的 Promise 至少要等 ms 毫秒后才 resolve/reject,即使函数本身执行得很快。
实现方式就是用 setTimeout 包裹函数调用,延迟 ms 后再执行 fn()。返回值形状保持不变,所以调用方侧的使用方式不需要改。
为什么返回包装函数
delayAll 的返回值是 () => Promise<any>[]——每个元素仍然是一个函数,不是直接执行的 Promise。这和 functions 的签名一致:都是「可执行的任务」,而不是「已启动的任务」。
这样做的意义在于,调用方仍然保留执行时机的控制权,可以按需要并行或串行地启动这些延迟函数。
和 Promise.all 的延迟区别
Promise.all 配合 sleep 也能实现延迟:
ts
const withDelay = fn => () => Promise.all([fn(), sleep(ms)]).then(([r]) => r)但这种写法下两个 Promise 是同时启动的:如果函数本身很慢,额外的 delay 基本不起作用;如果函数很快,sleep 才会决定最短耗时。而这里的实现是先等 ms 再启动函数,保证的是启动前等待时间,不是总耗时下限。
