ES6 Promise与Async的使用

用了es6这么久,一直没用过async,只在书上看过,也没实践过,总是忘。

现在记录一下笔记,其实Async应该是es7的内容。


 从Promise开始,Js异步编程的关键就是Promise了。

直接上代码,该编译环境是 Node v8+ ,如果低于可能需要babel来转译。

下面定义了两个函数,由于Promise一旦被创建立即执行,因此,用函数来控制,Promise有两种状态,一种 Resolve,一种是Reject,即成功与失败。Promise接受一个参数类型为:function。

下图很明显:(resolve,reject)=>{}这个就是我们传给Promise的参数,其中resolve与reject是回调函数,由js引擎提供,黑盒操作。我们可以在Promise的函数内部,调用这两个回调函数,注意:调用其一,Promise状态立刻改变,不可回退、比如,我们经常会使用ajax请求,当success时候,我们就调用Reslove函数告诉Promise改变状态为成功,如果ajax调用失败,我们可以调用reject告诉Promise状态改为失败,如下所见,这两个回调接受参数,我们可以通过一系列的异步任务,依次调用,处于后面的异步可以接受上层的返回数据。

    当然,我们也快可以返回新的Promise,实现连续异步的调用。,如p1与p2的返回。

一旦我们调用resolve函数,Promise就停止工作。我们可以使用then函数来获取接下来的工作,比如接收返回值,或者,这里可以明确知道,异步任务已经执行完毕,在这里执行下一个异步任务。

    then():该函数接收两个参数,第一个是Promise Resolve状态调用,第二个是reject状态调用。

我们可以看到,在p1().then(e=>console.log(e))只用了一个参数,因为对于reject我们使用另个catch函数来捕获错误。

如果不用catch,需要 p1().then(e=>xx,error=>xx)

这里有一个注意点:如果Promise一旦变为Resolve状态,catch将无法捕获错误。

比如,下面p2返回了一个新的Promise,该任务,我们手动执行了reject,该Promise变为reject状态,返回一个错误到上层p2,如果我们不在p2后面捕获catch,该错误会冒泡上层,如果在第一个p1后面捕获,将不会获取到,因为,p1此时已经是resolve了。

let p1 = () => {
    return new Promise((resolve, reject) => {
        console.log('3秒钟后,p1函数结束');
        setTimeout(() => {
            //返回Promise
            resolve(p2())
        }, 3000)
    })

};
let p2 = () => {
    return new Promise((resolve,reject)=> {
            console.log('p1结束,现在是第二个任务了!');
            resolve({key: 2, content: "第二个任务结束"})
        }
    )
};
 p1().then((res) => {
    console.log(res);
    p2().then((res2) => {
        console.log(res2);
        //返回Promise
        return new Promise((resolve ,reject)=> {
            console.log('开始第三个任务,这个任务是继续第二个的异步。');
            setTimeout(()=>reject({key:3,content:"第三个任务报错!"}),2000)
        })
    }).catch((error)=>console.log(error));
   
});
 //在resolve后调用catch无效,无法抛出错误,因为状态已经改变

执行结果:ES6 Promise与Async的使用_第1张图片

 

下面是Promise的两个包装函数。

还是代码,因为比较直观。

下图是包装的多个Promise。通过Promise.all()方法,将一系列的Promise实例合成一个Promise,该Promise状态受到子Promise的影响,当所有的子Promise变为Resolve,外层Promise变为Resolve状态,并将子Promise的返回值按照数组返回。一旦有一个子promise变为reject,promise变为Reject,返回第一个报错,停止。

 //多个异步操作包装
let p4 = ()=>{
    return new Promise((resolve)=>{
            resolve('p4 over')
    })
};
let p5 = ()=>{
    return new Promise((resolve)=>{
        resolve('p5 over')
    })
};
Promise.all([p4(),p5()]).then((e)=>console.log(e)).catch((e3)=>console.log('error:'+e3));

输出:ES6 Promise与Async的使用_第2张图片

 

下面是Promise.race(),字面意思就是看谁最先执行了。

和all不同的是,这个方法返回最先改变状态的子Promise返回值。

//Promise.race  返回最先改变状态的Promise的值
let p6  = ()=>{
    return new Promise((resolve)=>{
        console.log('p6 go');
       setTimeout(()=> resolve('p6 over'),4000)
    })
};
let p7 = ()=>{
    return new Promise((resolve)=>{
        console.log('p7 go');
        setTimeout(()=> resolve('p7 over'),2000)

    })
};
Promise.race([p6(),p7()]).then((e)=>console.log(e)).catch((ee)=>console.log(ee));

 输出:

ES6 Promise与Async的使用_第3张图片

 

最后是Asycn了。

Async就是对Promise的语法糖了,当然此处略过(generate....等)

定义与实例:下面并没有使用Promise,一会再用,先看看一般情况下,Async的使用。

 //Async
let a0 = ()=>{
    console.log('等待a0执行...');
         setTimeout(()=>{
             console.log('a0 over')
         },2000)
     };
let a00 = ()=>{
    console.log('等待a00执行...');
    setTimeout(()=>{
        console.log('a00 over')
    },3000)
};
let as1 = async ()=>{
    await a00();
    console.log('执行a00');
    await a0()
     };
as1().then();

首先定义多个 Async关键字。

其次有个await关键字,这个关键字:等待 后面的执行,一般是Promise或耗时任务,一会第二个例子就是用法。

输出:ES6 Promise与Async的使用_第4张图片

 

看看与Promise的配合。

下面的例子,定义了一个async函数,并且自动执行,我们看到输出结果,就一目了然了。

let a3 = ()=>{
    return new Promise((resolve)=>{
        setTimeout(()=>resolve('a3 over'),4000)
    })
};
let a4 = ()=>{
    return new Promise((resolve)=>
        setTimeout(()=>resolve('a4 over'),1000))
};

(async function async2() {
    console.log('开始序列执行a3,a4');
    let res3 = await a3();
    console.log(res3);
    let res4 = await a4();
    console.log(res4);
})();

输出:即使a3是最慢的,但是还是等它执行完,再执行a4的,如果使用Promise,需要一堆嵌套与then来处理。

ES6 Promise与Async的使用_第5张图片

 

你可能感兴趣的:(JavaScript笔记)