使用Lodash时,传递异步函数作为参数导致await失效问题
解决防抖异步函数await返回undefined的问题
问题根源
你使用的普通防抖函数(比如Lodash的debounce)不会返回被包裹异步函数的Promise结果。调用_debounceSearch时,它仅会安排目标函数在300ms后执行,当下直接返回undefined,因此await无法获取到异步请求的结果。
解决方案
自定义一个支持异步返回的防抖函数,让它返回Promise,这样await就能正常捕获异步操作的结果。
实现代码
首先定义支持Promise的防抖函数:
function debounceAsync<T extends (...args: any[]) => Promise<any>>( func: T, wait: number ): (...args: Parameters<T>) => Promise<ReturnType<T>> { let timeoutId: NodeJS.Timeout | null = null; let resolveQueue: ((value: ReturnType<T>) => void)[] = []; return (...args) => { return new Promise((resolve) => { if (timeoutId) clearTimeout(timeoutId); resolveQueue.push(resolve); timeoutId = setTimeout(async () => { timeoutId = null; const result = await func(...args); resolveQueue.forEach(res => res(result)); resolveQueue = []; }, wait); }); }; }
然后修改业务代码,用debounceAsync替换原有的debounce:
const _debounceSearch = debounceAsync( async (callback: (params: RequestParams) => any, value: string | undefined, language: string | undefined) => { const data = await callback({ q: value, lang: language }); console.log('data on search', data); return data; }, 300, ); // 现在await能正确拿到异步结果 const dataCompanies = await _debounceSearch(apiSearchCompany, searchValue, languageParam); console.log('dataCompanies', dataCompanies); if (dataCompanies) { setCompanySearchTags( dataCompanies.items.map((item: Company) => ({ value: item.id, label: item.name, checked: false })), ); }
补充说明
- 这个自定义防抖函数会收集所有调用的Promise resolve,当防抖延迟结束后,统一用最终的异步结果resolve所有等待的Promise,符合防抖“只响应最后一次操作”的逻辑。
- 如果使用Lodash的debounce,它本身不支持异步返回值的捕获,因此自定义实现是更直接的解决方式。
内容的提问来源于stack exchange,提问作者vantrong
相关产品推荐
相关产品推荐

