什么是回调地狱:
多层回调函数的相互嵌套,就形成了回调地狱,如下图:
代码耦合性太强,难以维护,大量冗余的代码嵌套,可读性差
Promise
-
Promise是一个构造函数 可以new出来一个 Promise实例
-
new出来的实例,代表一个异步操作
-
Promise.prototype上包含一个 .then()方法,可以通过原型链的方式访问到.then()方法
-
.then()方法可以来 预先指定 成功和失败的回调函数
-
.then()方法的特性: 如果上一个.then()方法返回了一个新的Promise实例对象,则可以通过下一个 .then()继续进行处理, 通过.then()的方法 链式调用,可以解决回调地狱的问题
-
.catch捕获错误: 在实例函数最后通过 .catch((err)=>{ }),捕获到错误可以
注意如果不希望前面的错误导致.then无法执行,则可以将.catch的调用提前,当.catch吧前面的错误捕获完成后,后面的 .then()回调可以正常 执行
所以如果.catch() 放到最后会 捕获前面的所有错误,如果不行因为前面的错误导致 后面代码无法正常执行,则可以吧.catch()提前
-
Promise.all()
该方法会发起并行的Promise异步操作,等所有的异步操作全部完成结束后才会执行下一步的 .then()操作
-
Promise.race()
该方法会发起并行的Promise异步操作,只要任何一个异步操作完成,就立即执行 .then()操作 (赛跑机制)
-
ES8中推出 async await 终极异步解决方案(这种书写风格,是最推荐的)
1、 async 和 await 必须成对出现
2、方法里面,第一个 await 前面的代码是同步执行的
同步任务和异步任务(ajax,setTimeout, nodejs -> 读写文件) console.log(123)
3 如果某个方法(函数)的返回值是 Promise实例对象,那么就可以在 前面用一个await 修饰,修饰完毕之后 这个返回值就不在是 Promise实例了,就变成了一个真正的值。 注意:如果内部使用 await修饰,那么这个 方法(函数)前面 必须被 async进行 修饰!!!
4 在async方法中,第一个await之前的代码会同步执行,包括和它并行的,await以下的代码会异步执行
宏任务和微任务
同步异步,因为JS是单线程语言,所以排队执行时,如果前面的任务比较耗时,那么后续任务无法马上执行,会导致一个假死状态,所以JS主线程会委托给宿主环境来处理这些耗时任务,又称为异步任务 如图下:
-
JS把异步任务分为两部分,一个是宏任务,一个是微任务
-
宏任务:(ajax setTimeout /setInterval)和微任务(then)特点:宏任务是一次执行一个;微任务一次是执行全部
-
微任务:Promise.then() , .catch()和.finally
-
process.nextTick等等
- 每一个宏任务执行完之后,都会检查是否存在待执行的微任务,如果有则执行完所有微任务,在执行下一个宏任务