JavaScript/Vue中如何发起多个异步调用实现无阻塞UI更新
问题原因
你当前的问题源于Promise.all的运行特性:它必须等待传入的所有Promise都兑现后才会触发后续回调,如果你将三个接口的赋值逻辑绑定到Promise.all的完成节点,哪怕其他接口早就返回了结果,也要等最慢的那个请求完成才会统一执行赋值,自然就会出现所有UI都要等全部请求结束才更新的情况。
解决方案
不要把三个接口的更新逻辑绑定在一起,让每个接口请求完成后立刻给自己对应的响应式变量赋值即可,哪个接口先返回,对应的下拉列表就会先渲染,互不影响:
setOrderStatuses: async function () { try { const res = await 调用订单状态接口 // 拿到结果立刻赋值,Vue会自动触发对应UI更新,不需要等其他请求 this.orderStatuses = res.data } catch (err) { // 单独处理当前接口报错逻辑 } }, setSpecialOrders: async function () { try { const res = await 调用特殊订单接口 this.specialOrders = res.data } catch (err) { // 单独处理当前接口报错逻辑 } }, setSubmitterNames: async function () { try { const res = await 调用提交人姓名接口 this.submitterNames = res.data } catch (err) { // 单独处理当前接口报错逻辑 } }, ... mounted: function () { this.$nextTick(function () { // 直接并发调用三个方法,不需要用Promise.all包起来 this.setOrderStatuses() this.setSpecialOrders() this.setSubmitterNames() }); },
如果你有后续逻辑必须等所有接口都完成才执行(比如隐藏全局加载提示),可以保留Promise.all,但不要把单个接口的赋值逻辑放到Promise.all的回调里:
mounted: function () { this.$nextTick(async function () { this.globalLoading = true const promiseList = [ this.setOrderStatuses(), this.setSpecialOrders(), this.setSubmitterNames() ] try { await Promise.all(promiseList) // 这里放需要等所有请求完成才执行的逻辑 } finally { this.globalLoading = false } }); },
补充说明
如果允许部分接口请求失败不影响其他逻辑,可以把Promise.all换成Promise.allSettled,避免一个接口报错打断整个等待逻辑。
内容的提问来源于stack exchange,提问作者Scott Baker
相关产品推荐
相关产品推荐

