javaScript的异步控制:async/await初试与进阶

作为有多年java皮毛式编程经验,python也能写几行的我,接触到javaScript之后居然觉得这是一门无法理解的语言,原因就在于它的异步处理。。我希望它按照我写的顺序执行,可是,它偏有自己的想法,使用console.log打印出来的执行顺序,总是让我无语。。。

以往都是通过.then(),昨天在同事的指导下,再次尝试async/await,居然成功了,而今天独自加班,就遇到了进阶需求,庆幸昨天学会了初阶。记录要点

初阶需求

上一篇自定义对话框组件中,当组件做完保存,需要通过emit通知父组件更新列表。我是这么写的:

onSave(){
    this.addUsrs();
    this.$emit("accountCreated");
    this.dialogVisible = false;
....
}

如你所想,addUsers中是一个后台保存的接口,所以,当父组件收到通知开始更新列表的时候,子组件的保存还正在执行呢,所以,父组件更新了个寂寞。。

修正方式1

.then()方法,将emit放到addUsers.then()中执行,具体可参考之前链式调用的博文,今天说说方法2.

修正方式2

1、将this.addUsers定义成一个async函数,其中使用await设置阻塞

//使用async,表示这是一个可以使用await控制执行顺序的同步函数
async addUsrs(){   
   //保存前的各种处理。。。。。。            
   await insertUsers(this.form.people);  //阻塞,执行保存结束后,才往下走
   this.$emit("accountCreated");    //重点:emit放到async函数里面来。走到这里的时候,上一步addUsers已经返回了
},

2、重点:把emit那一句放到addUsers里面来

只有在async函数内部,await才会等待返回后再执行下一步,如果emit还是像之前那样放置this.addUsers()后面,await是无法实现等待insert返回的。

如果emit那一句还是在onSave中,js的调用顺序大概是这样的:

1、执行onSave

2、执行addUsers,发现时间有点长,不等它,立刻返回

2、执行emit

3、父组件收到emit,开始更新列表。这时候addUsers有没有执行完,完全看运气。

如果emit在addUsers里面,js的调用顺序是这样的:

1、执行onSave

2、执行addUsers,发现时间有点长,不等它,立刻返回

2、执行dialogVisible = false,关闭对话框。

外层的主线执行完了,再看addUsers里面的支线

         2.1 执行insertUsers,发现时间有点长,但是前面有await,阻塞,等待执行完才返回

         2.2 insertUsers执行完返回,执行emit

         2.3 父组件收到通知,开始更新列表。

前面的序号,我分别用了两个2,不是笔误,表示这两个是同步执行的。可以看到,这里其实我们只是控制了emit一定要在insertUsers返回之后执行,其它的执行顺序,是不受我们控制的。而这个执行顺序,是按照函数的调用结构,层层返回的。我们只能控制某一层内的顺序,跨层的是无法控制的。

进阶需求:阻塞多接口

某页面created里面做初始化,一个数据需要同时使用两个接口的返回值,所以,我必须等两个接口都返回之后再做数据处理。但是,这两个接口之间是没有调用顺序的限制的,如果我使用链式调用虽然能实现功能,但是会影响效率。想到以前曾经听某项目在同事分析接口执行顺序的时候,提到过类似于接口1,接口2并发执行,返回后接口3和4顺序执行的说法。。于是,查了一下,果然有个阻塞多接口的方法:Promise.all()

方法1:await

async initProjectInfo(){
      const [fetch1Res,fetch2Res] = await Promise.all([fetchData1(this.projectFrm.unid),fetchData2(this.projectFrm.unid)]);

    //分别使用fetch1Res和fetch2Res进行数据处理
    .....

}

方法2:then

initProjectInfo(){
      Promise.all([fetchData1(this.projectFrm.unid),fetchData2(this.projectFrm.unid)]).then(result => {
        const result1 = results[0];
        const result2 = results[1];
        // 合并两个数组
        const mergedUserList = [...result1, ...result2];
        // 输出或处理合并后的数组
        console.log(mergedUserList);
});

   
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值