Promise用来解决异步函数的顺序执行问题:
一 三个包含异步函数的函数,顺序执行的状态:
function p1(callback){ console.log(‘p1起跑...‘); setTimeout(()=>{ console.log(‘p1到达终点‘); },5000) }; function p2(callback){ console.log(‘p2起跑...‘); setTimeout(()=>{ console.log(‘p2到达终点‘); },3000) }; function p3(callback){ console.log(‘p3起跑...‘); setTimeout(()=>{ console.log(‘p3到达终点‘); },1000) }; p1(); p2(); p3();
结果如下
二 回调地狱的解决方案:
每个函数的形参是一个回调函数,当每次函数内的程序执行完自动执行回调函数,这样就导致了函数的层层嵌套:
function p1(callback){ console.log(‘p1起跑...‘); setTimeout(()=>{ console.log(‘p1到达终点‘); callback(); },5000) }; function p2(callback){ console.log(‘p2起跑...‘); setTimeout(()=>{ console.log(‘p2到达终点‘); callback(); },3000) }; function p3(callback){ console.log(‘p3起跑...‘); setTimeout(()=>{ console.log(‘p3到达终点‘); callback(); },1000) }; p3(()=>{ p2(()=>{ p1(()=>{ console.log(`比赛结束`); }) }) })
输出结果:
三 promise方案
function p1(){ return new Promise(function(resolve,reject){ console.log(‘p1起跑...‘); setTimeout(()=>{ console.log(‘p1到达终点‘); resolve(1); },5000) }) }; function p2(){ return new Promise(function(resolve,reject){ console.log(‘p2起跑...‘); setTimeout(()=>{ console.log(‘p2到达终点‘); resolve(2); },3000) }) }; function p3(){ return new Promise(function(resolve,reject){ console.log(‘p3起跑...‘); setTimeout(()=>{ console.log(‘p3到达终点‘); resolve(3); },1000) }) };
//多个异步函数顺序执行:
p3()
.then(p2)
.then(p1)
.then(()=>{ console.log(‘比赛结束‘) })
.catch((reject)=>{
console.log(‘比赛终止‘);
});
//由于Promise.prototype.then/.then方法返回的是promise对象,所以可以链式调用
//等待多个异步任务完成才执行:
Promise.all([
p3(),
p2(),
p1()
]).then((arr)=>{
console.log(arr);
console.log(‘比赛结束‘);
})
//其中arr接收所有异步函数resolve(完成)的参
Promise的三个状态:
padding:初始状态,不成功也不失败
fulfilled:意味着操作成功完成(resolve) 当侦测到状态为fulfilled时,才会自动执行下一个异步函数
reject:意味着操作失败(reject)
Promise API :
.then() 得到异步任务的正确结果
.catch() 获取异常信息
.finally() 不管成功与否都会执行
Promise 对象方法:
.all() 同时处理多个异步任务,全部执行完才能得到结果
.race() 同时处理多个异步任务,只要有一个异步任务完成就有结果
Promise 属性:
.length 值为1
.prototype Promise构造器的原型
四 async await
定义函数的方法和步骤相较于Promise并没有减少,且异步函数必须支持Promise的样式:
function p1(){ return new Promise(function(resolve,reject){ console.log(‘p1起跑...‘); setTimeout(()=>{ console.log(‘p1到达终点‘); resolve(1); },5000) }) }; function p2(){ return new Promise(function(resolve,reject){ console.log(‘p2起跑...‘); setTimeout(()=>{ console.log(‘p2到达终点‘); resolve(2); },3000) }) }; function p3(){ return new Promise(function(resolve,reject){ console.log(‘p3起跑...‘); setTimeout(()=>{ console.log(‘p3到达终点‘); resolve(3); },1000) }) }; (async function(){ try{ var b=await p3(); b=await p2(b); b=await p1(b); console.log(‘比赛结束‘); }catch(err){ console.log(err); } })();
注意:
(1)await可让整段匿名函数暂时挂起,等待当前异步函数执行完成,再执行后续代码;
(2)async和await仅简化了Promise的调用部分,没有简化定义。且若想用await,则异步函数必须支持Promise的样式;
(3)使用try{...}catch(err){...}来获取异步函数中的错误(只有在async下的try catch才行),js普通的try catch属于主程序,不会等待异步程序的执行。
async让所有异步函数全部执行完:
(async function(){ Promise.all([ p1(), p2(), p3(), ]).then((res)=>{ console.log(res); }) })()
JS-16 (回调地狱、Promise、Async await)
原文:https://www.cnblogs.com/codexlx/p/12488730.html