先看看 async/await 的语法

async 函数返回一个 Promise 对象

async 函数内部 return 返回的值。会成为 then 方法回调函数的参数。

1
2
3
4
async function  f() {
    return 'hello world'
};
f().then( (v) => console.log(v)) // hello world

如果 async 函数内部抛出异常,则会导致返回的 Promise 对象状态变为 reject 状态。抛出的错误而会被 catch 方法回调函数接收到。

async function e(){
throw new Error('error');
}
e().then(v => console.log(v))
.catch( e => console.log(e));

async 函数返回的 Promise 对象,必须等到内部所有的 await 命令的 Promise 对象执行完,才会发生状态改变

也就是说,只有当 async 函数内部的异步操作都执行完,才会执行 then 方法的回调。

 
const delay = timeout => new Promise(resolve=> setTimeout(resolve, timeout));
async function f(){
await delay(1000);
await delay(2000);
await delay(3000);
return 'done';
}
f().then(v => console.log(v)); // 等待6s后才输出 'done'
 

正常情况下,await 命令后面跟着的是 Promise ,如果不是的话,也会被转换成一个 立即 resolve 的 Promise
如下面这个例子:

async function  f() {
return await 1
};
f().then( (v) => console.log(v)) //

如果返回的是 reject 的状态,则会被 catch 方法捕获。

Async 函数的错误处理

async 函数的语法不难,难在错误处理上。
先来看下面的例子:

 
let a;
async function f() {
await Promise.reject('error');
a = await 1; // 这段 await 并没有执行
}
f().then(v => console.log(a));
 

如上面所示,当 async 函数中只要一个 await 出现 reject 状态,则后面的 await 都不会被执行。
解决办法:可以添加 try/catch。

 
// 正确的写法
let a;
async function correct() {
try {
await Promise.reject('error')
} catch (error) {
console.log(error);
}
a = await 1;
return a;
} correct().then(v => console.log(a)); //
 

如果有多个 await 则可以将其都放在 try/catch 中。

如何在项目中使用呢  让我们结合Vuex来试试:

如何引入Vuex  以及编写

stroe.js

 
// stroe.js
import Vue from 'vue'
import Vuex from 'vuex'
import actions from './actions' Vue.use(Vuex) export const name = 'contract' const state = {
// 数据字典
initData: [],
number: ''
} const mutations = {
// 获取数据字典
SET_INIT_DATA (_state, obj) {
_state.initData = obj
},
// 获取分单申请ID集合
SET_NUMBER(_state, data) {
_state.number = data
console.log(_state)
}
} // 向外暴露store 对象
const store = new Vuex.Store({
namespaced: true,
name,
state,
actions,
mutations,
}) // 模块动态注册 项目庞大接口数量很大是便于管理 有疑惑 直戳 https://vuex.vuejs.org/zh/guide/modules.html 去vuex官网看看解释的更详细
store.registerModule(name, {
namespaced: true,
name,
state,
actions,
mutations,
}) export default store
 

actions.js 文件

 
// actions.js
import axios from 'axios'; const ajax = {
// 获取数据字典
GET_INIT_DATA: `agreement/init?`,
// 获取编号
GET_CONTRACT_NUMBER: `agreement/archive?`,
// 保存基本信息
SUBMIT_INFO: `agreement/submit/basic?`
}
// 提取公共部分
const API_URL = 'product/v1/middle/'; // 增加前缀
let INTERFACE = {};
for (let key in ajax) {
INTERFACE[key] = API_URL + ajax[key];
}
// 获取编号
function getContractNumber({commit}) {
return new Promise((resolve, reject) => {
axios.get(INTERFACE.GET_CONTRACT_NUMBER).then(data => {
commit('SET_NUMBER', {data}) // 改变state.number
resolve(data.data)
}).catch((err) => {
window.Alert(err)
})
})
}
// 获取数据字典
async function getInitData({commit, state}, params) {
 const num = await getContractNumber()
return new Promise((resolve, reject) => {
axios.get(INTERFACE.GET_INIT_DATA).then((data) => {
    commit('SET_INIT_DATA', {data}) // 改变state.initData
resolve(data.data)
}).catch((err) => {
window.Alert(err) // 全局错误提示
})
})
}

// 获取详情
function getInfo(id) {
return new Promise((resolve, reject) => {
// 写法2 模板字符串语法
axios.get(`apply/v1/${id}/input?`).then(data => {
resolve(data.data)
}).catch((err) => {
window.Alert(err) // 全局错误提示
})
})
}

// 提交
async function onSubmit({commit}, params) {
const result = await getInfo()
console.log(result)
return new Promise((resolve, reject) => {
axios.post(`${INTERFACE.SUBMIT_INFO}/${result.num}/products`, {...params}).then(data => {
resolve(data)
}).catch((err) => {
window.Alert(err) // 全局错误提示
})
})
} export default {
saveContrantInfo,
getContractNumber,
getInitData,
getInfo,
onSubmit
}
 

index.vue文件调用

 
<script>
import { name as moduleName } from '@/store'
export default {
data() {
return {
    // 基本信息
contractInfo: {},
    // 数据字典
    baseData: []
}
},
created() {
// 获取基本信息 若要then有返回值 actions 必须 resolve() 不然 then 方法没用
this.$store.dispatch(`${moduleName}/getInfo`).then(data => {
console.log(data)
})
// 获取数据字典
this.$store.dispatch(`${moduleName}/getInitData`).then(data => {
Object.assign(this.baseData, data)
})
},
methods: {
// 获取编号
async getNumber() {
     // 在 actions 函数里 await 也行 看具体需求 此例只作为演示 await 调用
const obj = await this.$store.dispatch(`${moduleName}/getContractNumber`)
this.contractInfo.fileNo = obj.fileNo
},// 提交
submit() {
this.$store.dispatch(`${moduleName}/onSubmit`, this.contractInfo).then(data => {
console.log(data)
})
}
}
}
</script>

以上就是 vuex 结合 async/await 的简单应用事例了。欢迎指正不足不对之处。

Vuex结合 async/await 优雅的管理接口请求的更多相关文章

  1. async/await 处理多个网络请求同步问题

    1.async/await是基于Promise的,是进一步的一种优化,await会等待异步执行完成 getProjectTask(id){ this.axios.get('/api/v1/task/' ...

  2. js中promise解决callback回调地狱以及使用async+await异步处理的方法

    1.callback回调地狱 function ajax(fn) { setTimeout(()=> { console.log('你好') fn() }, 1000) } ajax(() =& ...

  3. Axios及其async await封装

    Axios(IE8+) 基于promise的http库可用于浏览器与node.js 1.特性 支持promise API 拦截请求和相应 转换请求数据和响应数据 取消请求 自动转换JSON数据 客户端 ...

  4. 已配置好的vue全家桶项目router,vuex,api,axios,vue-ls,async/await,less下载即使用

    github 地址: https://github.com/liangfengbo/vue-cli-project 点击进入 vue-cli-project 已构建配置好的vuejs全家桶项目,统一管 ...

  5. 优雅地 `async/await`

    async/await 虽然取代了回调,使用类似同步的代码组织方式让代码更加简洁美观,但错误处理时需要加 try/catch. 比如下面这样,一个简单的 Node.js 中使用 async/await ...

  6. Vue实例中封装api接口的思路 在页面中用async,await调用方法请求

    一般我们写小型的项目是用不到封装axios实例 但是当我们写大型项目时  接口有时候多到有上百个接口,那我们在请求一次调用一次接口,接口上好多都是重复的,这个时候我们就可以封装axios实例,既节省了 ...

  7. 如何优雅地处理Async/Await的异常?

    译者按: 使用.catch()来捕获所有的异常 原文: Async Await Error Handling in JavaScript 译者: Fundebug 本文采用意译,版权归原作者所有 as ...

  8. 【限时免费】AppBoxCore - 细粒度权限管理框架(EFCore+RazorPages+async/await)!

    目录 前言 全新AppBoxCore RazorPages 和 TagHelpers 技术架构 页面处理器和数据库操作的异步调用 Authorize特性和自定义权限验证过滤器 Authorize登录授 ...

  9. 【C# TAP 异步编程】三、async\await的运作机理详解

    [原创] 本文只是个人笔记,很多错误,欢迎指出. 环境:vs2022  .net6.0 C#10 参考:https://blog.csdn.net/brook_shi/article/details/ ...

随机推荐

  1. python-selenium,关于页面滑动的操作

    //移动到元素element对象的“顶端”与当前窗口的“顶部”对齐 ((JavascriptExecutor) driver).executeScript("arguments[0].scr ...

  2. zabbix 监控Nginx和PHP

    原理 Nginx和PHP(5.3及以上版本)都自带了一个状态页,默认没有开启,通过开启这个状态页即可获取实时的工作状态. Nginx状态获取 Nginx的配置默认是拒绝通过IP来访问,我们可以再默认虚 ...

  3. Mysql 按天自动分区,合并老分区

    适用于每天一个分区...不断加分区,导致分区不够用的情况 CREATE DEFINER=hehe@XXXXXX PROCEDURE p_auto_partition_day(IN databaseNa ...

  4. Linux共享内存的管理

    在进程通信应用中会用到共享内存,这就涉及到了IPC,与IPC相关的命令包括:ipcs.ipcrm(释放IPC).IPCS命令是Linux下显示进程间通信设施状态的工具.我们知道,系统进行进程间通信(I ...

  5. The POM for XXX is invalid, transitive dependencies (if any) will not be available解决方案

    今天,某个开发的环境在编译的时候提示警告The POM for XXX is invalid, transitive dependencies (if any) will not be availab ...

  6. oracle 11g亿级复杂SQL优化一例(数量级性能提升)

    自从16年之后,因为工作原因,项目中就没有再使用oracle了,最近最近支持一个项目,又要开始负责这块事情了.最近在跑性能测试,配置全部调好之后,不少sql还存在性能低下的问题,主要涉及执行计划的不合 ...

  7. Redhat7.4 vim编辑无颜色解决

    背景 发现使用vim时, 统一颜色, 不区分关键字 解决 vim /etc/profile 在文件的末尾加入下面这一行 export TERM=xterm

  8. python简说(九)函数

    一.列表生成式 s =[1,2,3,4,5,6,7,8]for i in s: print(i+1)res = [ i+1 for i in s]res = [str(i) for i in s] 二 ...

  9. 我写的RunTime函数之一,为类的某个属性赋值以及方法交换

      1,为属性赋值 #import <UIKit/UIKit.h> @interface UIViewController (RunTime) - (BOOL)setPropertyVal ...

  10. java中读取配置文件的方法

    转自:http://blog.csdn.net/stypace/article/details/38414871 一.使用org.apache.commons.configuration 需要使用的是 ...