跳至主要內容

回调地狱

guodongAndroid大约 2 分钟

回调地狱

回调比构建自己的线程通信机制更简单。当涉及简单的函数时,它们的语法也相当易读。然而,多数情况下你通过某个方式连接或组合多个函数调用,最后将结果转换成更复杂的对象。

在这些情况下,代码变得非常难以编写、维护和推理(代码的行为)。由于不能从回调中返回值,只能把返回值传递给 lambda 块,所以必须得嵌套回调。它类似于在集合上嵌套 forEach 或 map 语句,其中每个操作都有自己的 lambda 参数。

当嵌套回调或 lambdas 时,会产生大量的大括号 '{}',每个大括号都自成一个局部范围。这种结构被称为缩进地狱——或者回调地狱。获取图片、调整图片大小和图片上传是一个很好的例子:

fun uploadImage(imagePath: String) {
    showLoadingSpinner()
    loadImage(imagePath) { image ->
		resizeImage(image) { resizedImage ->
        	uploadImage(resizedImage) {
                hideLoadingSpinner()
            }
        }
    }
}

和以前一样,您在上传之前显示上传进度条。首先,从文件中加载图片后需要继续调整它的大小。接下来,当调整完图片大小后,将开始上传图片。最后,当图片上传完成后,将隐藏进度条。

可能你首先注意到的是形成阶梯状代码结构的大括号和缩进的数量。然而这只是一个不是很复杂的操作,就已经使得代码难以阅读。当构建复杂的操作时,嵌套的层次只会更多。嵌套的代码不仅难以阅读,后期维护起来也非常困难。同时,对理解业务逻辑和流程来说也是一大阻力。如果尝试在两个回调之间添加逻辑或者更改某个 lambda 的返回结果类型,可能会破坏后面的 lambda。

此外,有些人开始发现回调很难掌握。它们陡峭的学习曲线,加上难以理解和缺乏可扩展性,迫使人们寻找异步编程的其他解决方案。人们发现了响应式编程。你将在下一节中看到响应式编程如何解决嵌套问题。