什么是回调地狱?如何解决回调地狱

一、什么是回调地狱呢?

	地狱这个词不陌生吧!对,没错就是那个十八层地狱的地狱,一层一层的地狱。

1、同步API,异步API的区别

这个问题呢,需要从Node.js的API说起,这里就会有人问了?博主你不是说回调地狱的问题吗,怎么说到API了,别急,看博主一步一步的解释给你听:

同步API 是从上到下依次执行,前面的代码会阻塞后面的代码执行
请看下面这个代码


这里我写了一个for询还1000次,在循环里面打印,在循环体后面是另外的一个打印结果
结果是什么呢?
这个需要你自己去敲一下代码才能更好的了解喔!

for(var i=0; i<1000; i++){
    
    
	console.log(i);
}
console.log('循环体后面的代码')

异步API不会等待API执行完后在向下执行代码
看下下面这个代码,会是如何执行呢?

console.log('代码开始执行')
//异步操作 setTimout
setTimout(() =>{
    
     console.log('5秒后执行代码') },5000);//5000就是5秒
setTimout(() =>{
    
     console.log('0秒后执行代码')},0);
console.loh('代码结束执行');

这里的执行顺序是:
代码开始执行
代码结束执行
0秒后执行代码
5秒后执行代码

逻辑梳理:先执行同步的API,在去执行异步的API
      同步API有两个  分别是两个console.log
      异步API也有两个 分别是setTimout
      异步API里面的定时器会先执行0  在执行5

2、Node.js中的异步API

	使用fs.readFile(‘./demo.txt’,(err,result) =>{});
	上面这个就是一个异步API
	是使用系统模块fs去查看文件

如果异步API后面的代码执行依赖当前异步API的执行结果,但实际上后续代码在执行的时候异步API还没有返回结果,这个问题怎么解决呢?

	fs.readFile(‘./demo.txt’,(err,result) =>{});
	console.log('文件打印结果')

3、写一个使用异步API,造成的回调地狱案例

案例需求:依次读取A文件,B文件,C文件

  1. 首先需要创建一个js的文件
  2. 然后分别创建1.txt 2.txt 3.txt
  3. 在每个文本里面写分别写上1 2 3
  4. 这样我们3个文件就创建好了,进入码代码的环节啦
const fs = require('fs')

fs.readFile('./1.txt','utf8',(err,result1) =>{
    
    
    console.log(result1);
    fs.readFile('./2.txt','utf8',(err,result2) =>{
    
    
        console.log(result2);

        fs.readFile('./3.txt','utf8',(err,result3) =>{
    
    
            console.log(result3);

        })
    })
});

执行这个js文件,执行结果是正确的,是不是没毛病!
但是这我们只写了3个,要是我们写18个呢

const fs = require('fs')

fs.readFile('./1.txt','utf8',(err,result1) =>{
    
    
    console.log(result1);
    fs.readFile('./2.txt','utf8',(err,result2) =>{
    
    
        console.log(result2);

        fs.readFile('./3.txt','utf8',(err,result3) =>{
    
    
            console.log(result3);
            fs.readFile('./3.txt','utf8',(err,result3) =>{
    
    
                console.log(result3);
                fs.readFile('./3.txt','utf8',(err,result3) =>{
    
    
                    console.log(result3);
                    fs.readFile('./3.txt','utf8',(err,result3) =>{
    
    
                        console.log(result3);
                        fs.readFile('./3.txt','utf8',(err,result3) =>{
    
    
                            console.log(result3);
                            fs.readFile('./3.txt','utf8',(err,result3) =>{
    
    
                                console.log(result3);
                                fs.readFile('./3.txt','utf8',(err,result3) =>{
    
    
                                    console.log(result3);
                                    fs.readFile('./3.txt','utf8',(err,result3) =>{
    
    
                                        console.log(result3);
                                        fs.readFile('./3.txt','utf8',(err,result3) =>{
    
    
                                            console.log(result3);
                                
                                        })
                                    })
                                })
                            })
                        })
                    })
                })
            })
        })
    })
});

这样你能理解了吗?这样一层回调嵌套一层回调,是不是有点像地狱的样子!这样的代码也不易去维护。

二、怎么解决回调地狱呢?

	Promise的出现就是解决Node.js异步编程中回调地狱的问题
基础语法
let promise = new Promise((resolve,reject) =>{
    
    
	setTimout(() =>{
    
    
	if(true){
    
    
	//resolve将异步API的执行结果传递出去
	    resolve({
    
    name:"张三"})
	}else{
    
    
		//reject 也是一个函数,当判断失败的时候,将结果传递出去
  		reject('失败了')
  }	
},2000);
})
//成功了
promise.then(result => console.log(result));//{name:‘张三’}
		.catch(error => console.log(error));//失败了

1、使用Promise来完成我们之前做的案例

  1. 创建一个js文件
  2. 文件可以就用之前的文件
  3. 开始代码的编写
//1、引入系统模块fS
const fs = require('fs');

//2、创建一个promise对象
let promise = new Promise((resolve,reject) =>{
    
    

    fs.readFile('./1.txt','utf8',(err,result) =>{
    
    
        if(err !=null){
    
    
            reject(err);
        }else{
    
    
            resolve(result);
        }
    });
});
//文件成功的信息
promise.then((result) =>{
    
    
    console.log(result);
})
//文件失败的信息
.catch((err) =>{
    
    
    console.log(err);
})

2、改进的方法

const fs = require('fs')
function p1(){
    
    
    return new Promise((resolve,reject) =>{
    
    
        fs.readFile('./1.txt','utf8',(err,result) =>{
    
    
            resolve(result);
        })
    })
}
function p2(){
    
    
     return new Promise((resolve,reject) =>{
    
    
        fs.readFile('./2.txt','utf8',(err,result) =>{
    
    
            resolve(result);
        })
    })
}
function p3(){
    
    
    return new Promise((resolve,reject) =>{
    
    
        fs.readFile('./3.txt','utf8',(err,result) =>{
    
    
            resolve(result);
        })
    })
}
//依次执行1、2、3
p1().then((r1) =>{
    
    
    console.log(r1);
    //return p2
    return p2();
})
.then((r2) =>{
    
    
    console.log(r2);
    //return p3()
    return p3();
})
.then((r3) =>{
    
    
    console.log(r3);
})

读到这里,你知道什么是回调地狱了吗?并且如何解决它了吗?
切记!看代码或者看文章的记忆并不深刻哟,要自己去敲代码,这个在面试中也是经常会出现哟!码字不易,希望能一键三连

猜你喜欢

转载自blog.csdn.net/weixin_45054614/article/details/115032044
今日推荐