JavaScript(React) 如何让async函数的await总耗时达到指定时长
弹性等待异步函数实现方案
你需要的功能可以通过Promise.all同时触发请求任务和最低延时任务实现,原理是Promise.all会等待所有传入的异步任务全部完成后才会继续执行,刚好匹配你需要的「总耗时不低于1000ms」的要求。
基础实现代码
const loadingHandler = async (func, target) => { setIsLoading(true); // 同时启动请求和1000ms延时任务,两者都完成后才会往下执行 await Promise.all([ func(target), new Promise(r => setTimeout(r, 1000)) ]); setIsLoading(false); };
逻辑说明
- 如果
func请求耗时小于1000ms:请求会先完成,Promise.all会继续等待延时任务走完剩余的时间,总耗时刚好为1000ms - 如果
func请求耗时大于等于1000ms:延时任务会先完成,Promise.all会继续等待请求返回,总耗时等于请求耗时,不会额外等待
进阶处理
需要返回请求结果
如果需要拿到func的返回值,可以按如下写法调整:
const loadingHandler = async (func, target) => { setIsLoading(true); // Promise.all返回结果按传入顺序排列,第一项就是func的返回值 const [funcResult] = await Promise.all([ func(target), new Promise(r => setTimeout(r, 1000)) ]); setIsLoading(false); return funcResult; };
异常兼容(无论请求成功/失败都保证至少1000ms loading)
如果需要避免请求报错提前终止等待逻辑,可增加异常处理:
const loadingHandler = async (func, target) => { setIsLoading(true); try { const [funcResult] = await Promise.all([ func(target), new Promise(r => setTimeout(r, 1000)) ]); return funcResult; } catch (err) { // 可在此处统一处理请求报错逻辑 throw err; } finally { // 无论请求成功失败都会关闭loading状态 setIsLoading(false); } };
内容的提问来源于stack exchange,提问作者Sokker
相关产品推荐
相关产品推荐

