React中如何等待异步post请求完成后再执行后续保存操作?
问题根因
- 所有axios请求都是异步操作,你调用
saveProducts()后没有等待请求返回就直接执行后续的getProducts()、setProductId()逻辑,此时POST提交商品的请求还没完成,Products表还没有新数据,products数组还是旧值,所以取到的id始终是上一条的,看起来就“少一位”。 - React的状态更新(set开头的方法)是异步批量执行的,调用
setProductId()后,当前函数作用域内拿到的productId还是旧值,要等到下一次组件渲染才会更新。 - 用
setTimeout延迟2秒的方案完全不可靠,网络波动时很容易出现请求超时还没返回的情况,稳定性极差。
修复方案
核心是用async/await规范化异步流程,直接复用接口返回的product_id,减少不必要的状态依赖和重复请求:
- 改造
saveProducts函数,让它返回Promise,直接把新增成功的product_id返回,避免再去拉取全量商品列表再匹配。 - 改造
saveStock为async函数,所有异步操作前加await等待执行完成,删掉不可靠的setTimeout。
修改后代码示例:
// 改造后返回Promise,直接返回新增的product_id const saveProducts = async () => { const data = { barcode: barcode, name: name, }; try { const response = await axiosInstance.post('/products/', data); setBarcode(response.data.barcode); setName(response.data.name); // 这里可以更新状态,同时直接把id返回给调用方 const newProductId = response.data.product_id; setProductId(newProductId); return newProductId; } catch (e) { console.log(e); throw e; // 抛出错误让上层调用方处理 } } const saveStock = async () => { let currentProductId; const temp = products.filter(product => product.barcode == barcode); if (!temp.length) { // 等待商品新增完成,直接拿到返回的新product_id,不需要再调用getProducts取列表 currentProductId = await saveProducts(); } else { currentProductId = temp[0].product_id; } // 所有前置操作完成后,直接提交库存请求,不需要setTimeout try { const data = { stock_id: stock_id, product_id: currentProductId, count: count, }; const response = await axiosInstance.post('/stocks/', data); setStockId(response.data.stock_id); setProductId(response.data.product_id); setCount(response.data.count); } catch (e) { console.log(e); } }
额外优化建议
- 如果不需要全量商品列表做其他逻辑,甚至可以删掉
getProducts()调用,直接复用接口返回的商品数据,减少不必要的接口请求。 - 提交过程中可以加个按钮loading状态,避免用户重复点击触发多次请求。
内容的提问来源于stack exchange,提问作者silviaa11
相关产品推荐
相关产品推荐

