回调地狱【Callback Hell】
前提知识点:
单线程和异步:
- JS是单线程语言,只能同时做一件事儿 (例子:做一个ajax请求去加载资源,或者说弄一个定时器,先等待1秒钟后干嘛,如果按照单线程这个只能同时做一件事儿,那么它在这个事情中,它就卡住了,卡住的话鼠标点不了,js不执行。这就是同时做一件事,这就是js单线程的本质。)
- 浏览器和node.js已支持JS启动进程,如Web Worker
- Js和DOM渲染共用同一个线程,因为JS可修改DOM结构
一、 遇到等待(网络请求,定时任务)不能卡住
二、 需要异步(解决单线程等待的问题)
三、 异步基于callback函数形式来调用的
四、 异步不会阻塞代码执行
五、 同步会阻塞代码执行
何为回调?
回调函数是必须得依赖另一个函数执行调用,它是异步执行的,也就是需要时间等待
何为回调地狱?
例子:Ajax应用,比如http请求
在不刷新浏览器的情况下,当你执行DOM事件时,比如页面上点击某链接,回车等事件操作,浏览器会悄悄向服务端发送若干http请求,携带后台可识别的参数,等待服务器响应返回数据,这个过程是异步回调的,当许多功能需要连续调用,环环相扣依赖时,它就类似下面的代码
/* mock ajax */
function request(options) {
setTimeout(function() {
var response = {
code:'success',
content: options.data
};
options.success(response);
},Math.ceil(Math.random()*100))
}
request({
url: 'ajax1',
data: 1,
success: function(res1) {
console.log(res1.content);
request({
url: 'ajax' + res1.content
data: 2,
success: function(res2) {
console.log(res2.content);
request({
url: 'ajax' + res2.content,
data: 3,
success: function(res3) {
console.log(res3.content);
request({
url: 'ajax' + res3.content;
data: 4,
success: function(res4) {
console.log(res4.content);
}
})
}
})
}
})
}
})
代码全部一层一层的嵌套,看起来就很庞大,很恶心,就产生了回调地狱!
回调地狱的缺点
- 代码耦合,一旦修改,原地爆炸。
- 无法使用try catch,就无法排错,也是原地爆炸。
什么是回调地狱(函数作为参数层层嵌套)
什么是回调函数(一个函数作为参数需要依赖另一个函数执行调用)
如何解决回调地狱?promise/generator/async await
总结
回调地狱最主要的就是因为功能逻辑代码嵌套的层次太多,导致可读性降低,维护困难,避免回调地狱的最重要的方面是将功能移开,保持代码简单,不嵌套并分成小模块,也就是多多进行代码封装,将你所要的属性和方法用function关键字包裹起来,而且还要给它取一个有意义的名字,例如:页面上弹框,显示,隐藏,下拉等各个功能小模块,分别用有名函数给包裹起来,少用匿名函数,以便可以重复的多次使用,这也是可以便于程序流程的理解!!
除了常见的一种回调函数作为异步处理,还有promise,generator,async await是处理异步处理的方式。
为了更好的理解本文,请结合下面的博客,更加方便的理解:
https://blog.csdn.net/weixin_43352901/article/details/107553694 // 同步和异步的区别是什么?
https://blog.csdn.net/weixin_43352901/article/details/107554775 // 异步的应用场景
https://blog.csdn.net/weixin_43352901/article/details/107556742 // Promise的基本使用
https://blog.csdn.net/weixin_43352901/article/details/107946370 // 一文让你彻底理解Promise对象及其常用用法!!