如何将jQuery Deferred实现的异步逻辑改为Vue nextTick写法?
改造方案说明
核心错误原因
- 混淆了
$nextTick和异步请求等待的作用:$nextTick仅用于等待当前批次的DOM更新完成,无法等待API请求这类异步IO操作结束 - 原错误代码在发起请求后直接调用
$nextTick,没有等待接口返回、Vuex状态更新就尝试读数据,自然拿不到最新值 - Vuex的
action本身就会返回内部异步操作的Promise,原代码额外封装jQuery Deferred属于冗余逻辑
正确改造代码
async/await 写法(更简洁)
methods: { ...mapActions(['fetchOverdraftLogs', 'setOverdraftFilters', 'fetchUserEventsCsvFile']), loadData: async function(filters) { // 等待接口请求完成、Vuex状态更新 await this.fetchOverdraftLogs({ params: this.filtersToSend(filters) }) this.setFilterValues() // 若需要等setFilterValues触发的DOM更新完成再返回,保留以下nextTick,否则可删除 await this.$nextTick() // 保持和原代码一致的返回值,方便外部链式调用 return this.getOverdraftLogs } }, computed: { ...mapGetters(['getOverdraftLogs']) }
Promise then 写法
methods: { ...mapActions(['fetchOverdraftLogs', 'setOverdraftFilters', 'fetchUserEventsCsvFile']), loadData: function(filters) { return this.fetchOverdraftLogs({ params: this.filtersToSend(filters) }) .then(() => { this.setFilterValues() // 不需要等待DOM的话可直接return this.getOverdraftLogs,去掉nextTick return this.$nextTick() }) .then(() => { return this.getOverdraftLogs }) } }, computed: { ...mapGetters(['getOverdraftLogs']) }
注意事项
- 不要用箭头函数定义Vue的methods,箭头函数会绑定父级作用域的this,导致this指向不是Vue实例,引发方法/属性调用失败
- 如果仅需要读取Vuex的状态,不需要操作更新后的DOM,可以直接去掉
$nextTick相关逻辑,等待请求完成后直接读getter即可
内容的提问来源于stack exchange,提问作者grozdeto
相关产品推荐
相关产品推荐

