为了健壮性,要对每一步操作进行执行结果检查,代码写出来很臃肿,不知道怎么精简。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
async function func1(){
let res
try {
let res = await db.call()
} catch(e) {
console.error(e)
return {
err: true,
msg: 'fail in func1'
}
}
return {
err: false,
data: res
}
}

// func2 ...
// func3 ...

async function main(){
let res = await func1()
if (res.err) {
return {
err: true,
msg: 'fail in func1'
}
}

res = await func2()
if (res.err) {
return {
err: true,
msg: 'fail in func2'
}
}

res = await func3()
if (res.err) {
return {
err: true,
msg: 'fail in func3'
}
}

return {
err: false,
msg: 'ok'
}
}

因为看过UNP中作者使用Wrapper函数,所以希望也能将func1之类的被调用函数直接取代main来返回。期望的形态应该是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
async function func1(){
let res
try {
let res = await db.call()
} catch(e) {
console.error(e)
EXIT({ // <---- 希望能从这里接管 main 的控制流
err: true,
msg: 'fail in func1'
})
}
return {
err: false,
data: res
}
}

// func2 ...
// func3 ...

async function main(){
let res = await func1() // 如果上面的可以实现,这里就相当于自带错误处理,出错时可以提前返回
res = await func2()
res = await func3()

return {
err: false,
msg: 'ok'
}
}

问题是,在func1return之类的都只能回到调用方,只有throw才可能影响到控制流,throw当然也行,类似

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
async function main(){
try {
let res = await func1()
res = await func2()
res = await func3()
} catch (e) {
return {
err: true,
msg: e
}
}

return {
err: false,
msg: 'ok'
}
}

一般来说,会要求try的部分尽可能小,不知道对于JavaScript来说是不是也是这样的,把所有都包起来似乎不是很好的处理方式。

在StackOverflow上看到这个问答介绍了怎么给一个function包上catch。

然后发现另一篇,是express的next,貌似和我想要的很像,看了下express的中间件,似乎正式解决我的问题,只是它的这个是针对Web的,不知道对于非Web的有没有专门的对应东西。另外有时间还是要学习下express和koa。