Vue.js中created调用异步接口mounted合并数组为空如何解决
Vue生命周期钩子异步请求执行顺序问题解答
问题根因
该问题的核心是异步请求的非阻塞特性导致的执行顺序错位:
- 最初代码中
created钩子内调用的retrieveSellOffers和getAllProducts都是异步网络请求,调用后不会阻塞JS主线程执行,浏览器会直接往后执行mounted钩子中的mergeSellOffersProducts方法,此时两个网络请求还未收到返回结果,因此products和sellOffers还是初始的空数组。
现有解决方案原理
你改用async/await的修复方案逻辑完全正确:
- 给两个数据请求方法添加
async标记后,方法会返回Promise对象 - 在
mounted钩子中通过await依次等待两个请求执行完成、拿到返回值赋值给对应变量后,再执行合并方法,此时两个数组已经完成赋值,自然能拿到正确的非空数据。
可选优化方案
因为两个数据请求互相没有依赖关系,不需要串行等待,可以使用Promise.all并行发起请求,减少整体数据加载耗时:
async mounted() { // 同时发起两个请求,待全部返回后再执行合并逻辑 const [sellOffersRes, productsRes] = await Promise.all([ SellOfferServices.getAllBySellerId(localStorage.sellerId), ProductServices.getAll() ]) this.sellOffers = sellOffersRes.data this.products = productsRes.data this.mergeSellOffersProducts() }
另外原有合并方法存在逻辑缺陷:直接按索引匹配两个数组的元素,若两个数组长度不一致、或者元素排序不对应,会出现匹配错误的问题,建议修改为按productId映射匹配:
mergeSellOffersProducts () { // 把products转为以_id为key的映射表,提升匹配效率 const productMap = new Map(this.products.map(item => [item._id, item])) this.arr3 = this.sellOffers.map(offer => { const matchedProduct = productMap.get(offer.productId) return { id: offer._id, price: offer.price, description: matchedProduct ? matchedProduct.description : '' } }) }
内容的提问来源于stack exchange,提问作者Stormy
相关产品推荐
相关产品推荐

