如何使用async/await改写useEffect解决异步接口时序异常问题
解决方案
你当前的问题本质是没有等待createName的异步请求完成就直接调用了getName,两个异步请求并行执行,自然会出现createName延迟导致getName拿不到最新数据的情况。
useEffect的回调函数不能直接声明为async(因为async函数默认返回Promise,不符合React要求useEffect只能返回清理函数或undefined的规则),所以需要在useEffect内部定义异步执行函数再调用,修改后的代码如下:
useEffect(() => { // 内部定义异步执行函数 const handleNameFlow = async () => { if (names.length !== 0) { // 等待createName请求完成后再执行后续逻辑 await createName(id); } // 保证createName执行完成后再调用getName await getName(id); }; handleNameFlow(); // 注意把id也加入依赖数组,避免闭包捕获旧值 }, [names, id]);
如果需要处理组件卸载时终止未完成的请求、避免内存泄漏,可以加入AbortController做优化:
useEffect(() => { const controller = new AbortController(); const signal = controller.signal; const handleNameFlow = async () => { try { if (names.length !== 0) { // 把signal传给接口函数,内部可以用signal判断是否终止请求 await createName(id, signal); } await getName(id, signal); } catch (err) { // 忽略主动取消请求产生的报错 if (err.name !== 'AbortError') { console.error('请求执行失败: ', err); } } }; handleNameFlow(); // 清理函数:依赖更新或组件卸载时终止未完成的请求 return () => controller.abort(); }, [names, id]);
内容的提问来源于stack exchange,提问作者Sai Krishnadas
相关产品推荐
相关产品推荐

