回调地狱的存在普遍是由于函数的层层嵌套,导致后续代码规模增大之后代码可读性降低,逻辑难以理清,然而回调地狱本身并不是bug或者是错误的代码。接下来将通过几个简单的例子来说明回调地狱,只需了解setTimeout方法便可继续阅读。
抛开理论,假如现在有这样一个需求:运行一段JavaScript代码,要求在1秒后控制台输出数字“1”,输出数字“1”之后接下来2秒之后输出“2”,输出数字“2”之后接下来3秒后输出数字“3”。
乍一看是不是很简单?用最简单的setTimeout方法即可解决,正确答案如下:
setTimeout(function(){ console.log(1); setTimeout(function(){ console.log(2); setTimeout(function(){ console.log(3); },3000) },2000) },1000)
如果你的答案是下面这样子的话,需要去了解JS的异步与同步机制,以及setTimeout是异步任务这个知识点。如果你的答案跟上面的正确答案一样,那就可以直接跳过下面这段代码。
setTimeout(function(){ console.log(1); },1000); setTimeout(function(){ console.log(2); },2000); setTimeout(function(){ console.log(3); },3000);
现在修改一下需求:运行一段JavaScript代码,要求在1秒后控制台输出数字“1”,输出数字“1”之后接下来2秒之后输出“2”,输出数字“2”之后接下来3秒后输出数字“3”,以此类推直到输出数字“13”。
按照一开始的解题思路,不过是增多几行代码罢了,正确答案如下:
setTimeout(function(){ console.log(1); setTimeout(function(){ console.log(2); setTimeout(function(){ console.log(3); setTimeout(function(){ console.log(4); setTimeout(function(){ console.log(5); setTimeout(function(){ console.log(6); setTimeout(function(){ console.log(7); setTimeout(function(){ console.log(8); setTimeout(function(){ console.log(9); setTimeout(function(){ console.log(10); setTimeout(function(){ console.log(11); setTimeout(function(){ console.log(12); setTimeout(function(){ console.log(13); },13000) },12000) },11000) },10000) },9000) },8000) },7000) },6000) },5000) },4000) },3000) },2000) },1000)
上面这段代码就是“回调地狱”(callback hell)
回调地狱的存在普遍是由于函数的层层嵌套,导致后续代码规模增大之后代码可读性降低,逻辑难以理清,然而回调地狱本身并不是bug或者是错误的代码,通常使用Promise来解决回调地狱。