JS-16 之回调地狱、Promise、Async await

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);
	})
})()
原文地址:https://www.cnblogs.com/codexlx/p/12488730.html