异步请求返回处理之finally的用途,代码规范摸索【玩转JavaScript】
前言
最近在改动老代码时,发现了一个有趣的现象。对于异步请求返回结果处理中,使用finally做兜底处理,不同的页面并不统一,也就是有的页面使用了,有的页面没使用,没使用的页面增加了额外的失败的处理。
所以finally到底要不要统一?
本着代码规范化原则的思维,我准备一探究竟。
finally 听说好用?
编程欢乐小剧场
某:来吧,是时候做个决定了。
一:我不知道怎么回答,多说的讯息。
某:我们的异步请求,到底用不用 finally?让我们来统一下。
一:好问题啊,赞。
某:所以?
一:统一的思维,确实符合规范化编程的思想,但是。
某:我就知道有转折。
一:过度的统一,会让代码缺失灵活性。
某:鱼与熊掌不可兼得。
一:好文采。
某:......
一:其实,应该用逆向思维思考这个问题,是不是存在不能使用finally的场景存在。
某:原来如此。
try...catch and finally
finally 块中的语句会在 try 块和 catch 之后执行。这里有两个而且。
- 无论是否抛出异常,finally 块中的语句都会执行。
- 如果抛出异常,即便没有 catch 处理异常,finally 块中的语句也会执行。
try {
await request({ url: `http://localhost:${server.address().port}` });
} finally {
server.close();
}
如上,server 都会执行关闭操作。
正向思维
借 finally 的特质合并「按钮防重&&数据重置」功能
现实项目中,新增/编辑数据的弹窗,是不可重复提交的,且提交之后,无论提交成功与否,表单数据需要置空(实际情况可能比举例中更复杂一些)。
通常,我们的功能处理如下:
http(params)
.then(() => {
message.success('操作成功');
})
.finally(() => {
// 重置数据
setData({});
// 设置按钮不可点击
setConfirmLoading(false);
});
既然 finally 块中的语句也会执行,便可以把 try...catch 中相同的处理,提炼到 finally 块中,可减少重复的设置。
逆向思维
如果 try 语句中有 return,finally 依旧会执行吗?
function func() {
try {
return 'try';
} finally {
return 'finally';
}
}
let res = func();
console.log('res:', res);
打印结果
// > res: finally
通过打印结果,不难发现,try 语句中有 return,finally 块中的语句依旧是执行了的。我们因此又得到一条规则:
如果 finally块 语句中返回一个值,那么这个值将会成为整个 try-catch-finally 的返回值。
为什么这么说呢,等我改造一下上面的代码:
function func() {
try {
console.log(1);
return 'try';
} catch (e) {
console.log(2);
} finally {
console.log(3);
return 'finally';
}
}
let res = func();
console.log('res:', res);
打印结果
// > 1
// > 3
// > res: finally
再看现在的打印结果,try 语句中是执行的,只不过,finally 中的 return「覆盖了」try 中的 return。
总结
来说一下实验的结论:
- 无论是否抛出异常,无论有没有 catch 处理异常,finally 块中的语句都会执行。
- 借助 finally 的特质可以帮助合并按钮防重和数据重置的功能。
- 如果 finally块 语句中返回一个值,那么这个值将会成为整个 try-catch-finally 的返回值。
实现思维方面的收获是:
正向和逆向这两个不同的思维面,也分享了开发过程中不错的功能联想。
作者:非职业「传道授业解惑」的开发者叶一一
简介:「趣学前端」、「CSS畅想」系列作者,华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。
- 点赞
- 收藏
- 关注作者
评论(0)