目前后台是微服务架构,所以不同的业务模块会请求到不同的地址,而不同的环境(测试/beta/生产)会携带不同的请求头进行区分,同时每个请求都有固定的参数携带,所以需要对请求进行统一的封装和管理。在这里记录一下封装请求的代码。

目前请求统一封装至 services 文件夹,按照后台模块名进行区分。每个请求都会封装成一个Promise,使用async/await进行异步请求管理。注意同时发起的多个请求使用Promise.all封装为一个新的Promise进行管理,防止串行请求影响性能。

1
2
3
4
5
let resp = await OpService.getProjects()
console.log(resp)

let requests = [UcService.getCurrentDeptLoginInfo(), UcService.getDepts()]
let [currentDeptResp, deptsResp] = await Promise.all(requests)

1

  • utils/request.js
  • 封装请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//module区分模块,模块名称封装在 【src/config/module.js】里
//path 是请求的文件路径
//data 是传入数据
//noAccessToken 大部分时间都是false ,极端情况 比如登陆、投诉之类的不需要
get(module, path, data, noAccessToken = false) {
let p = new Promise(async function (resolve, reject) {
try {
let config = await BaseService.getConfig()
let client = await BaseService.getClient(module)
let services = config.services[module]
let resp = await client.get(makeUrl(services.host, path, data, noAccessToken), {
headers: {
accept: 'application/json',
}
})
resolve(resp)
} catch (e) {
await handleError(e)
reject(e)
}
})
return p
},

2

  • eg: src\services.js
  • 封装请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 登录后获取当前基础信息接口
*/

//R是在build/webpack.base.conf.js里声明过的封装方法
//里面包含了基础的请求信息

function getCurrentDeptLoginInfo() {
let p = new Promise(async function (res, rej) {
try {
let resp = await R.get(Config.module.UC, '/user/get_current_dept_login_info')
res(resp)
} catch (e) {
rej(e)
}
})
return p
}

3 应用请求

  • src\app.js
  • 调用封装的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
async handleDeptCommand(id) {
Loading.show()
try {
let resp = await UserService.switchDept(id)
if (resp.errcode == 0) {
let resp2 = await UserService.getCurrentDeptLoginInfo()
BaseService.setBasicData(resp2.info)
this._renderBasicData(resp2.info)
this.$router.push('/')
} else {
console.error(new Error('errcode: ' + resp.errcode))
}
} catch (e) {
console.error(e)
} finally {
Loading.hide()
}
}