一、什么是回调地狱呢?

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

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 p2return p2();
})
.then((r2) =>{console.log(r2);//return p3()return p3();
})
.then((r3) =>{console.log(r3);
})

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

2021.3月31日更新

3、ES7 优化(异步函数)

异步函数是异步编程语法的终极解决方案,它可以让我们将异步代码写成同步的形式,让代码不再有回调函数嵌套,使代码变得清晰明了

const fn = async() =>{};
async function fn(){}

之前的案例,优化后的代码如下

const fs = require('fs');
const  promisify  = require("util").promisify;
const readFile = promisify(fs.readFile);async function run() {let  r1 = await readFile('./1.txt','utf8')let r2 =  await readFile('./2.txt','utf8')let r3 = await readFile('./3.txt','utf8')console.log(r1);console.log(r2);console.log(r3);
}
run();

4、总结

//1.在普通函数定义的前面加上async关键字 普通函数就变成的异步函数
//2.异步函数默认的返回值是promise对象
//3.在异步函数内部使用throw关键字进行错误的抛出//await关键字
//1.它只能出现在异步函数中
//2.await promise 它可以暂停异步函数的执行 等待promise对象返回结果后在向下执行async function p1() {return '1';
}
async function p2() {return '2';
}
async function p3() {return '3';
}
async function run() {let r1 = await p1()let r2 = await p2()let r3 = await p3()console.log(r1);console.log(r2);console.log(r3);}
run();

什么是回调地狱?如何解决回调地狱相关推荐

  1. 回调地狱以及解决回调地狱 - promise嵌套变链接 - 解决终极办法 - async 和 await

    回调函数? 当一个函数被当做参数传递时,这个函数就叫做回调函数-  callback 通常使用回调函数来处理异步代码 当异步代码执行结束后,需要执行的代码就要放在回调函数中 回调地狱? 当回调函数嵌套 ...

  2. 什么是回调地狱?解决回调地狱的方法

    什么是回调地狱?(代码执行顺序的一种操作(解决异步)) 回调地狱的概念:回调函数里面嵌套回调函数. //地狱回调setTimeout(function () { //第一层console.log('1 ...

  3. 回调地狱,解决回调地狱,回调地狱的终极解决方案

    回调地狱示例 使用promise的链式调用解决回调地狱 async/await:回调地狱的终极解决方案

  4. 回调地狱及解决回调地狱的终极目标

    目录 一.回调地狱的定义 二.解决回调地狱的终极目标 三.promise语法 3.1  定义 3.2  封装promise函数 3.3  语法形式 四.async 和 await语法 4.1  定义 ...

  5. promise解决回调地狱的问题

    什么是回调地狱 怎么解决回调地狱的问题 要了解什么是回调地狱,首先要了解 什么是同步,什么是异步函数 同步函数:当一个函数是同步执行时,那么当该函数被调用时不会立即返回,直到该函数要做的事情全部做完之 ...

  6. 什么是回调函数?回调函数有什么缺点?如何解决回调地狱问题?

    什么是回调函数?回调函数有什么缺点?如何解决回调地狱问题? 参考文章: (1)什么是回调函数?回调函数有什么缺点?如何解决回调地狱问题? (2)https://www.cnblogs.com/kzxi ...

  7. JavaScript中的回调地狱及解决方法

    JavaScript中的回调地狱及解决方法 1.回调地狱 在使用JavaScript时,为了实现某些逻辑经常会写出层层嵌套的回调函数,如果嵌套过多,会极大影响代码可读性和逻辑,这种情况也被成为回调地狱 ...

  8. es6解决回调地狱问题

    本文摘抄自阮一峰老师的 http://es6.ruanyifeng.com/#docs/generator-async 异步 所谓"异步",简单说就是一个任务不是连续完成的,可以理 ...

  9. Promise使用,return的运用,解决回调地狱

    Promise使用,return的运用,解决回调地狱 回调地狱 httpBookModel.getHotList().then((res) => {console.log(res)httpBoo ...

  10. Promise解决回调地狱写法

    这里可以使用Promise来解决回调地狱的问题! 那么我们这里有一个需求,就是我们需要读取三个 .txt 文件,需要第一个文件读取完成后才能读取第二个文件以此类推. 那么这里来一个Promise的错误 ...

最新文章

  1. 十个隐藏_LOL手游:新版增加42个英雄,大白兔:10个隐藏T0角色
  2. 鲸鱼优化算法_Java 代码优化细节之比比谁更细
  3. mysql数据库死锁 情景一
  4. 2017校赛 问题 D: 我知道了,你知道了吗?【递归】
  5. boost::fibers::launch::post的测试程序
  6. 源码免杀--反调试代码,免杀爱好者必备的利剑
  7. 用函数计算搭建页面的前端CICD系统,提升访问体验
  8. ml302硬件手册_Cat.1模组ML302使用MQTT协议接入OneNet平台
  9. 一篇文章教你用matlab求定积分广义/变限积分
  10. 沪漂五年:我是如何从职场失意,走向皮实的人生?
  11. 拟一维喷管流动的数值解——亚声速-超声速等熵喷管流动的非守恒型CFD解法(MacCormack方法)
  12. Taro引入阿里图标
  13. SQLZOO刷题笔记
  14. 重磅!GitHub突然宣布,对全球人免费开放全部核心功能
  15. 《程序员升职记》2.繁忙的收发室
  16. (三)MAMP的安装及使用
  17. 导入keras训练好的模型报错解决OSError: Unable to open file (unable to open file: name = ‘model_3.h5’)
  18. NPOI读取excel中的上下标,转化为真实的下标
  19. u盘维护工具 linux,【制作简单,启动兼容性好的U盘维护工具:DOS工具+WINPE+PUPPY LINUX】...
  20. 哈工大2022年传输原理期末试题

热门文章

  1. 3.口袋西游人物属性(03)
  2. OpenProcessToken
  3. 基于springboot实现私人健身与教练预约管理系统【源码+论文】
  4. 织梦 wordpress_谁拥有WordPress,以及WordPress如何赚钱?
  5. TypeScript Dom操作
  6. python 按钮控件_python实现360皮肤按钮控件实例
  7. 一个汉字占多少个字节
  8. 部分正则表达式匹配所有数字,包括带小数点的数字
  9. 车牌识别在移动端的应用
  10. 为什么现在很多企业选择代理记账公司