Promise封装请求

一般我们在使用Promise链式调用会显得代码不那么优雅,如果出现嵌套的问题,可读性较就会很差。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

// 封装请求函数
const request = (url, params) => {
return new Promise((resolve, reject) => {
// ...do something
})
}

// 使用时
const handleLogin = () => {
request(
'/basic/login',
{
usename: 'yangfan',
password: '123456'
}
).then(res => {
// success do something
}).catch(err => {
// fail do something
})
}

promise reject catch 错误处理:async函数返回一个Promise对象,其内部抛出错误,会导致返回的Promise对象变为reject状态,可以通过catch函数进行错误兜底。

async/await

async/await他的作用是:用同步的方式执行异步操作

1
2
3
4
5
6
7
8
9
10
11
12
const handleLogin = async () => {
const res = await request('/basic/login', {
usename: 'yangfan',
password: '123456'
})

const info = await request('/basic/getuserinfo', {
id: res.id
})

setUserInfo(info)
}
1
| 错误处理:通过try...catch 将await错误包裹在try...catch代码块中,进行异常捕获。

await-to-js

await-to-js 已经帮我们做了这件事,我们可以看看它是怎么做的,它的源码只有短短十几行,我们应该读读它的源码,学学它的思想。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

/**
* @param { Promise } 传进去的请求函数
* @param { Object= } errorExt - 拓展错误对象
* @return { Promise } 返回一个Promise
*/
export function to(
promise,
errorExt
) {
return promise
.then(data => [null, data])
.catch(err => {
if (errorExt) {
const parsedError = Object.assign({}, err, errorExt)
return [parsedError, undefined]
}

return [err, undefined]
})
}

export default to;

简单使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

const handleLogin = async () => {

const [resErr, res] = await to(request('/basic/login', {
usename: 'yangfan',
password: '123456'
}))

if (resErr) {
// fail do somthing
return
}

const [userErr, info] = await to(request('/basic/getuserinfo', {
id: res.id
}))

if (userErr) {
// fail do somthing
return
}

setUserInfo(init);
}

源码总结:to 函数返回一个 Promise 且值是一个数组,数组之中有两个元素,如果索引为0的元素不为空值,说明该请求报错,如果索引0的元素为空值说明该请求没有报错,也就是成功。