精通Vue.js系列 │ Vuex中的异步操作

简介: Vuex中异步操作

640.jpg


在仓库的actions选项的动作函数中,可以包含异步操作,例如以下actionA()动作函数会异步提交someMutation()更新函数。


actions: {
  actionA ({ commit }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('someMutation')
        resolve()
      }, 1000)
    })
  }
}

以下代码在一个组件的方法忠派发actionA()动作函数。


this.$store.dispatch('actionA').then(() => {
  // 当actionA()动作函数中的异步操作执行完毕后,再执行then()函数指定的操作
  …
})

在仓库的一个动作函数中还可以派发另一个动作函数:

actions: {
  //…
  actionB ({ dispatch, commit }) {  //actionB()函数派发actionA()函数
    return dispatch('actionA').then(() => {
      commit('someOtherMutation')
    })
  }
}

此外,还可以通过async/await执行异步操作,例如:


//假定getData()和getOtherData()返回Promise对象
actions: {
  async actionA ({ commit }) {  //async表明当前函数包含异步操作
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') //等待actionA()的异步操作执行完毕
    commit('gotOtherData', await getOtherData())
  }
}

1、异步动作范例

以下位于src/main.js中的代码创建了一个包含actions选项的仓库store,包括addQuantityAction()和calculateAction()动作函数。

const store = createStore({
  state () {
    return {
      item: {
        name: '苹果',
        price: 3.8,
        quantity: 1,
        total :  3.8
      }
    }
  },

  mutations: {
    addQuantity(state){  //增加购买数量
      state.item.quantity++
    },
    calculate(state){  //计算总价格
     state.item.total=state.item.price * state.item.quantity
    }
  },

  actions: {
    addQuantityAction({commit}){
      return new Promise((resolve)=>{
        setTimeout(          //模拟异步操作
          ()=>{
             commit('addQuantity')
             resolve() 
          },2000)
      })
    },

    calculateAction({commit,dispatch}){
      //等购买数量增加后,再计算总价格 
      dispatch('addQuantityAction').then( ()=>{
        commit('calculate')
      })
    }
  }
})

以上代码中的动作函数的作用如下。

(1)addQuantityAction()动作函数:包含异步操作,过2秒后提交addQuantity()更新函数。

(2)calculateAction()动作函数:会派发addQuantityAction()动作函数,等到addQuantityAction()动作函数的异步操作执行完毕以后,再执行then()函数,从而提交calculate()更新函数。

例程1的AsyncJudge.vue定义了AsyncJudge组件,它的calculate()方法会向仓库派发calculateAction()动作函数。

■ 例程1 AsyncJudge.vue


<template>
  <div>
    <p>商品名字: {{item.name}}  </p>
    <p>单价: {{item.price}}  </p>
    <p>数量: {{item.quantity}}  
    <button @click="calculate">增加</button>  </p>
    <p>总价:{{item.total}}</p> 
  </div>
</template>
  
<script>
  import { mapState,mapActions } from 'vuex'

  export default {
    computed: mapState(['item']),
  
    methods: {
      ...mapActions({calculate: 'calculateAction'})  
    }
  }
</script>

在src/router/index.js中,为AsyncJudge组件设置的路由的路径为judge。通过浏览器访问http://localhost:8080/#/judge,会出现如图1所示的网页。在网页上单击“增加”按钮,就会看到在延迟2秒后,{{item.quantity}}及{{item.total}}的取值会发生相应的更新。

640.png


■ 图1 AsyncJudge组件的页面

2、使用async/await的范例

以下位于src/main.js中的代码创建了一个包含actions选项的仓库store,包括一个loadCustomerAction()动作函数,该动作函数用async标识,表明是包含异步操作的函数。


const store = createStore({
  state () {
    return {
      customer: '', 
      msg: ''
    }
  },

  mutations: {
    clearCustomer(state){
      state.msg='正在查询...'
      state.customer=''
    },
    loadCustomer(state,response){
      if(response.data !== null){
        state.customer=response.data
        state.msg=''
      }else
        state.msg='未找到匹配的数据!'    
    }
  },

  actions: {
    async loadCustomerAction({commit},id){
      commit('clearCustomer')  
      const response=await axios({
         baseURL: 'http://www.javathinker.net',
         url: '/customer',
         method: 'get',
         params: {id: id}
      })
      commit('loadCustomer',response) 
    }
  }
})

loadCustomerAction()动作函数会通过Axios请求访问服务器,查询与id匹配的customer对象。在异步调用axios()函数之前,会提交clearCustomer()更新函数,等到Axios的异步请求执行完毕,再提交loadCustomer()更新函数。

例程2的AsyncCustomer.vue定义了AsyncCustomer组件。它的getCustomer()方法会向仓库派发loadCustomerAction()动作函数。

■ 例程2 AsyncCustomer.vue


<template>
  <div>
    <p>输入id: <input v-model="id" />  
           <button @click="getCustomer">查询</button>  {{msg}} 
    </p>  
    <p>{{customer}}</p>
  </div>
</template>
  
<script>
  import {mapState} from 'vuex'
  export default {
    data(){ return {id: '' }},
    computed: mapState(['customer','msg']),
    methods: {
      getCustomer(){
        this.$store.dispatch('loadCustomerAction',this.id).then(
          ()=>{console.log(this.customer)}
        )
      }
    }
  }
</script>

在src/router/index.js中,为AsyncCustomer组件设置的路由的路径为cust。通过浏览器访问http://localhost:8080/#/cust,会出现如图2所示的网页。在网页上的id输入框输入1,再单击“查询”按钮,会看到网页先显示“正在查询...”,延迟一段时间后,再显示id为1的customer对象的信息。

640.png

■ 图2 AsyncCustomer组件的页面

目录
相关文章
|
13天前
|
前端开发 JavaScript 数据处理
在JavaScript中,异步函数是指那些不会立即执行完毕,而是会在未来的某个时间点(比如某个操作完成后,或者某个事件触发后)才完成其执行的函数
【6月更文挑战第15天】JavaScript中的异步函数用于处理非同步任务,如网络请求或定时操作。它们使用回调、Promise或async/await。
23 7
|
1月前
|
前端开发 JavaScript UED
深入理解 JavaScript 同步和异步,让网页灵动起来!
深入理解 JavaScript 同步和异步,让网页灵动起来!
|
1月前
|
JavaScript
Vue 中如何模块化使用 Vuex
Vue 中如何模块化使用 Vuex
17 0
|
3天前
|
自然语言处理 JavaScript 前端开发
JavaScript闭包是函数访问外部作用域变量的能力体现,它用于封装私有变量、持久化状态、避免全局污染和处理异步操作。
【6月更文挑战第25天】JavaScript闭包是函数访问外部作用域变量的能力体现,它用于封装私有变量、持久化状态、避免全局污染和处理异步操作。闭包基于作用域链和垃圾回收机制,允许函数记住其定义时的环境。例如,`createCounter`函数返回的内部函数能访问并更新`count`,每次调用`counter()`计数器递增,展示了闭包维持状态的特性。
18 5
|
1天前
|
前端开发 JavaScript
Promise是JavaScript解决异步问题的构造器,代表未来的不确定值。
【6月更文挑战第27天】Promise是JavaScript解决异步问题的构造器,代表未来的不确定值。它避免了回调地狱,通过链式调用`.then()`和`.catch()`使异步流程清晰。
7 2
|
11天前
|
存储 JavaScript API
Vue状态管理深度剖析:Vuex vs Pinia —— 从原理到实践的全面对比
Vue状态管理深度剖析:Vuex vs Pinia —— 从原理到实践的全面对比
20 2
|
16天前
|
前端开发 JavaScript 开发者
JavaScript中的异步操作与回调地狱解决方法
JavaScript中的异步操作与回调地狱解决方法 在现代的Web开发中,JavaScript扮演着极为重要的角色,尤其是在处理网络请求、文件操作或者任何可能耗费时间的操作时。为了不阻塞程序的执行,JavaScript 提供了异步编程模型。本文将介绍JavaScript中的异步操作是什么,什么是回调地狱,以及如何解决回调地狱问题。 什么是异步操作? 异步操作指的是那些不会立即完成的操作,程序可以在等待异步操作完成的同时,继续执行其他代码。JavaScript通常使用事件循环机制处理异步操作,这使得它可以在不阻塞主线程的情况下执行任务。 常见的异步操作包括: 网络请求(如使用 XMLHt
9 2
|
22天前
|
监控 前端开发 JavaScript
JS Navigator.sendBeacon 可靠的、异步地向服务器发送数据
Navigator.sendBeacon 是一个用于发送少量数据到服务器的 API,尤其适用于在页面即将卸载时发送数据,如日志记录、用户行为分析等。 与传统的 AJAX 请求不同,sendBeacon 方法的设计目标是确保数据在页面卸载(例如用户关闭标签页或导航到新页面)时能够可靠地发送。 Navigator.sendBeacon 方法可用于通过 HTTP POST 将少量数据异步传输到 Web 服务器。 它主要用于将统计数据发送到 Web 服务器,同时避免了用传统技术(如:XMLHttpRequest)发送分析数据的一些问题。
23 1
|
25天前
|
前端开发 JavaScript 开发者
JavaScript异步编程艺术:深入浅出回调函数与异步挑战【含代码示例】
本文深入解析JavaScript异步编程,重点探讨回调函数和异步挑战。在单线程的JavaScript中,异步编程至关重要,回调函数是其基础。然而,回调地狱问题催生了Promise和async/await的出现。文章提供代码示例展示Promise和async/await的使用,并分享异步编程最佳实践,包括错误处理、资源管理和性能优化。遇到问题时,建议通过明确异步流程、逐步调试和异常捕获来解决。最后,文章强调异步编程的未来发展,鼓励开发者掌握最新工具并探讨更高效的异步解决方案。
22 2
|
7天前
|
XML 移动开发 前端开发
JS设置Ajax为同步或异步
JS设置Ajax为同步或异步
6 0