一、回调地狱
1、回调函数:把一个函数作为参数传递给另一个函数,在另一个函数中作为参数的函数不会立即执行,只有当满足某个条件后才会执
2、同步任务:主线程任务队列中的程序依次执行,只有当前一个任务执行结束后才会执行后一个任务
3、异步任务:不会进入主主线程队列,它会进入异步的队列。前一个任务是否执行完毕不影响下一个任务的执行
|
异步任务又称为不阻塞任务:前一个任务的执行不阻塞后一个任务的执行
(1)可读性差,维护困难
(2)无法进行return和throw
(3)多个回调之间无法建立联系
二、Promise对象:是一个原生的js对象,为了解决回调地狱问题,可以替换掉回调函数。是一个新的异步任
(1)pending[待定] 初始状态
(2)resloved[实现] 操作成功
(3)rejected[被否决] 操作失败
(1)当promise对象的状态发生改变时就会触发后面的.then()的响应函数来执行后续的操作
(2)状态一经改变就不会再变
(3)promist对象一经创建就会立即执行 —- 异步任务的同步效果
强调:promise为什么能连续的.then —->因为.then里面的回调函数的返回值也是一个promist对象
Promise(function(resolve,reject){ })
resolve:表示异步操作成功后的回调函数,将promise对象的状态由初始状态转换到成功状态,并将回调函数的执行结果传
递出去,由下一个then来接收……
reject:表示异步操作失败后的回调函数,在回调函数执行错误时调用,并将错误的信息作为参数传递出去,由catch来接收…
function fn(str){//返回值是一个Promise对象 //创建Promise对象 let p = new Promise((resolve,reject)=>{ var flag = true if(flag){ resolve(str) }else{ reject('失败') } }) return p } fn('武林要以和为贵').then((data)=>{ console.log(data) return fn('要讲武德')//返回一个Promise对象 }).then((data)=>{ console.log(data) return fn('不要窝里斗')//返回一个Promise对象 }).then((data)=>{ console.log(data) }).catch((e)=>{ console.log(e) }) |
4、Promise的all方法:实现了异步任务的并行执行能力
function getWidth(){//返回Promise对象 return new Promise((resolve,reject)=>{ setTimeout(resolve(5),1000) }) } function getheight(){//返回Promise对象 return new Promise((resolve,reject)=>{ setTimeout(resolve(4),1000) }) } Promise.all([getWidth(),getheight()]).then((result)=>{//调用两个异步函数,实现并行运行 console.log('结果',result) }) |
三、async函数和await函数:ES7出现的
1、Promise对象的缺陷:虽然跳出了回调地狱,但是在流程复杂的代码中会出现很多的then,这样导致代码的可读性也很差
2、async/await出现的原因:是对Promise的一种优化,又称为Promise的语法糖
var sleep = function(time){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('#####') },time) }) } var start = async function(){ console.log('start') await sleep(3000).then((data)=>{ console.log(data) }) console.log('end') } start() |
3、async/await的使用规则
(1)await关键字只能在async标识的函数中使用
(2)await后面可以直接跟一个 Promise对象(更多的是跟一个返回Promise对象的表达式)
(3)await函数不能单独使用
(4)await可以直接拿到Promise中resolve中的数据。
function fn(str){//返回值是一个Promise对象 //创建Promise对象 let p = new Promise((resolve,reject)=>{ var flag = true if(flag){ resolve(str) }else{ reject('失败') } }) return p } async function test(){ let r1 = await fn('武林要以和为贵') let r2 = await fn('要讲武德') let r3 = await fn('不要搞窝里斗') console.log(r1) console.log(r2) console.log(r3) } test() |
4、promise和async/await区别
(1)promise是ES6中出现,async/await是在ES7中出现
(2)async/await的写法更优雅
(3)对reject状态的捕捉方式不同
a、promise采用.then后面跟.catch方法捕捉,通常.catch放在最后
b、async/await可以用.then后面跟.catch方法捕捉,也可以使用try…catch方式捕捉