如何才能减少代码的嵌套层级?

2018-05-03 14:51:44 +08:00
 kuoruan

Linus Torvalds:

If you need more than 3 levels of indentation, you ’ re screwed anyway, and should fix your program.

如果你的代码里需要有超过三层的缩进,那么你已经搞砸了,应该修改你的代码。

这里贴一段我写的代码

function do_kcptun_update(btn) {
	btn.disabled = true;
	btn.value = '<%:Downloading...%>';
	add_remove_page_notice(true);
	var kcptun_update_url = '<%=dsp.build_url("admin/services/kcptun/update/kcptun")%>';
	(new XHR()).get(kcptun_update_url, {
		token: token_str,
		url: kcptun_info ? kcptun_info.url.download : ''
	}, function (x, json) {
		if (x && x.status == 200) {
			if (json.code == 0) {
				btn.value = '<%:Extracting...%>';
				(new XHR()).get(kcptun_update_url, {
					token: token_str,
					task: "extract",
					file: json.file,
					subfix: kcptun_info ? kcptun_info.type : ''
				}, function (x, json) {
					if (x && x.status == 200) {
						if (json.code == 0) {
							btn.value = '<%:Moving...%>';
							(new XHR()).get(kcptun_update_url, {
								token: token_str,
								task: "move",
								file: json.file
							}, function (x, json) {
								if (x && x.status == 200) {
									if (json.code == 0) {
										on_update_success(btn);
									} else {
										on_request_error(btn, json);
									}
								} else {
									on_request_error(btn);
								}
							});
						} else {
							on_request_error(btn, json);
						}
					} else {
						on_request_error(btn);
					}
				});
			} else {
				on_request_error(btn, json);
			}
		} else {
			on_request_error(btn);
		}
	});
}

这是一段用来更新程序的 JavaScript,但是代码的继续执行依赖于上一次请求的成功执行。 可苦于没有好的优化方案,只能写出这种垃圾代码了。

7059 次点击
所在节点    程序员
51 条回复
zn
2018-05-03 16:07:08 +08:00
短路疗法了解一下。



其实就是楼上说的反向判断啦,先判断不符合条件的,尽快返回,后面剩下合法条件再做处理。
GoLand
2018-05-03 16:07:56 +08:00
early return.
qiumaoyuan
2018-05-03 16:16:07 +08:00
@kuoruan 封装是唯一正确的办法。不仅仅是封装成方法,还可以封装成类。

要嵌套多少层是业务逻辑决定的,而不是代码编写方式决定的。

其实你不知道你调用的代码库背后已经有了多少层的逻辑判断。
evitceted
2018-05-03 16:22:48 +08:00
rx
yongjing
2018-05-03 16:25:52 +08:00
callback hell
sampeng
2018-05-03 16:48:45 +08:00
封装成函数+promise 可以解决问题。。但 promise 也可能陷入调用链太长的问题。总比这样强不是。

楼上有说封装成函数没减少层级。有些逻辑是没办法减少的。但封装函数最少一眼能看明白逻辑,让代码清晰可见的最终目的不就是可读性尚可。

early return 也是一个很好的手段。稍微减少一些不必要判断层级。

唔。。少用匿名函数。。简直是噩梦
pluschen
2018-05-03 16:56:22 +08:00
啥?封装成函数没减少层数?
别逗,哪有什么层数?都是 JMP。
sampeng
2018-05-03 16:58:58 +08:00
仔细看了代码。。只是各种 else 处理错误而已。。。这个。。很难吗?
xiaojunjor
2018-05-03 17:02:32 +08:00
kuoruan
2018-05-03 17:12:59 +08:00
@sampeng #28 不好意思,我能力不行,让您见笑了
zhlssg
2018-05-03 17:16:50 +08:00
async await ,提早 return
saulshao
2018-05-03 17:19:49 +08:00
If you need more than 3 levels of indentation, you ’ re screwed anyway, and should fix your program.
这句话本来就是说的是一个函数里面的事情。
cs923
2018-05-03 17:31:50 +08:00
RxJs(没用过 应该能解决)
Justin13
2018-05-03 18:21:09 +08:00
就嵌套而言,可以考虑 early return,抽函数,就业务而言,可以考虑使用更优雅的库,promise,async
we2ex
2018-05-03 18:23:59 +08:00
@xiaojunjor #29 正解,第一时间想到的也是这篇文章
banricho
2018-05-03 18:25:14 +08:00
这个代码的根本原因在于直接原生 XHR …

不用任何库的情况下,封装一个 fetch
剩下是处理异步的问题,楼上都说了
最后才是 if 的问题
wlwood
2018-05-03 18:42:50 +08:00
其实,感觉,用 react.js, vue 这些框框,这种地狱应该挺好解决啊
noNOno
2018-05-03 20:08:10 +08:00
歪个楼,动感光波?
Exia
2018-05-03 20:14:50 +08:00
楼主的地狱回调,能自己看懂就还不错了,应该用 promise 吧,我也要向这个方面提升一下。
LevineChen
2018-05-03 20:22:12 +08:00
多个 return 也不好 可以用 do while ( false ) break 实现类似功能

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/451758

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX