Vue中的同步调用和异步调用方式

目录
  • Vue的同步调用和异步调用
    • Promise实现异步调用
    • async /await方法实现同步调用
  • Vue同步和异步的问题
    • 基本语法
    • 实例

Vue的同步调用和异步调用

Promise实现异步调用

异步调用,增加a、b两个方法,并在mounted中调用。 观察客户端,并没有按照方法执行的顺序输出,使用Promise实现了异步调用。

观察客户端,并没有按照方法执行的顺序输出,使用Promise实现了异步调用。

async /await方法实现同步调用

使用async 和 await配合promise也可以实现同步调用,nuxt.js中使用async/await实现同步调用效果

观察服务端控制台发现是按照a,b的调用顺序输出1,2,使用async/await实现了同步调用。

Vue同步和异步的问题

之所以想到写这个问题是因为在工作中遇到一些相关的问题,最后用ES7的async-await 来解决这个问题。话不多述 ,进正题。

基本语法

async functionbasicDemo() {
    let result = await Math.random();
    console.log(result);
}
basicDemo();
// 0.6484863241051226//Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: undefined}

上述代码就是async-await的基本使用形式。有两个陌生的关键字async、await,同时函数执行结果似乎返回了一个promise对象。

  • async
async functiondemo01(){
    return 123;
}
demo01().then(val=> {
    console.log(val);// 123});

若 async 定义的函数有返回值,return 123;相当于Promise.resolve(123),没有声明式的 return则相当于执行了Promise.resolve();

  • await

await 可以理解为是 async wait 的简写。await 必须出现在 async 函数内部,不能单独使用。

functionnotAsyncFunc(){
    await Math.random();
}
notAsyncFunc();//Uncaught SyntaxError: Unexpected identifier

await 后面可以跟任何的JS 表达式。虽然说 await 可以等很多类型的东西,但是它最主要的意图是用来等待 Promise 对象的状态被 resolved。如果await的是 promise对象会造成异步函数停止执行并且等待 promise 的解决,如果等的是正常的表达式则立即执行。

functionsleep(second){
    return new Promise((resolve, reject) => {
        setTimeout(()=> {
            resolve(' enough sleep~');
        }, second);
    })
}functionnormalFunc(){
    console.log('normalFunc');
}async functionawaitDemo(){
    await normalFunc();
    console.log('something, ~~');
    let result = await sleep(2000);
    console.log(result);// 两秒之后会被打印出来}
awaitDemo()

希望通过上面的 demo,大家可以理解我上面的话。

实例

举例说明啊,你有三个请求需要发生,第三个请求是依赖于第二个请求的解构第二个请求依赖于第一个请求的结果。若用 ES5实现会有3层的回调,若用Promise 实现至少需要3个then。一个是代码横向发展,另一个是纵向发展。今天指给出 async-await 的实现哈~

我们仍然使用 setTimeout 来模拟异步请求

functionsleep(second, param){
    return new Promise((resolve, reject) => {
        setTimeout(()=> {
            resolve(param);
        }, second);
    })
}async functiontest(){
    let result1 = await sleep(2000, 'req01');
    let result2 = await sleep(1000, 'req02' + result1);
    let result3 = await sleep(500, 'req03' + result2);
    console.log(`${result3}${result2}${result1}`);
}
test();

错误处理

上述的代码好像给的都是resolve的情况,那么reject的时候我们该如何处理呢?

functionsleep(second){
    return new Promise((resolve, reject) => {
        setTimeout(()=> {
            reject('want to sleep~');
        }, second);
    })
}async functionerrorDemo(){
    let result = await sleep(1000);
    console.log(result);
}
errorDemo();// VM706:11 Uncaught (in promise) want to sleep~// 为了处理Promise.reject 的情况我们应该将代码块用 try catch 包裹一下async functionerrorDemoSuper(){
    try {
        let result = await sleep(1000);
        console.log(result);
    } catch (err) {
        console.log(err);
    }
}
errorDemoSuper();// want to sleep~

小心你的并行处理!!!

我这里为啥加了三个感叹号呢~,因为对于初学者来说一不小心就将 ajax 的并发请求发成了阻塞式同步的操作了,我就真真切切的在工作中写了这样的代码。await 若等待的是 promise 就会停止下来。业务是这样的,我有三个异步请求需要发送,相互没有关联,只是需要当请求都结束后将界面的 loading 清除掉即可。 刚学完 async await 开心啊,到处乱用~

functionsleep(second){
    return new Promise((resolve, reject) => {
        setTimeout(()=> {
            resolve('request done! ' + Math.random());
        }, second);
    })
}async functionbugDemo(){
    await sleep(1000);
    await sleep(1000);
    await sleep(1000);
    console.log('clear the loading~');
}
bugDemo();

loading 确实是等待请求都结束完才清除的。但是你认真的观察下浏览器的 timeline 请求是一个结束后再发另一个的(若观察效果请发真实的 ajax 请求)

那么,正常的处理是怎样的呢?

async functioncorrectDemo(){
    let p1 = sleep(1000);
    let p2 = sleep(1000);
    let p3 = sleep(1000);
    await Promise.all([p1, p2, p3]);
    console.log('clear the loading~');
}
correctDemo();// clear the loading~

以上。

好了,这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Vue中的同步和异步调用顺序详解

    目录 Vue的同步和异步调用顺序 例如 Vue两个异步方法顺序执行 第一个异步方法 第二个异步方法 Vue的同步和异步调用顺序 Vue中的方法调用顺序是依次进行的,方法体内部也是依次执行的,但是,两个方法体的执行顺序并不能严格控制. 以下方法中都带有promise函数或异步调用.     initUserData() {       this.getPsCountryList() // 1 获取国家列表stateOptions,方法内同步       this.getTimeZone() //

  • vue同步父子组件和异步父子组件的生命周期顺序问题

    关于vue组件的引入方式有两种 一. 同步引入 例子: import Page from '@/components/page' 二.异步引入 例子:const Page = () => import('@/components/page') 或者: const Page = resolve => require(['@/components/page'], page) 两种引入方式的不同之处在于: 同步引入时生命周期顺序为:父组件的beforeMount.created.beforeMoun

  • Vue 同步异步存值取值实现案例

    1.vue中各个组件之间传值 1.父子组件 父组件–>子组件,通过子组件的自定义属性:props 子组件–>父组件,通过自定义事件:this.emit(′事件名′,参数1,参数2,...); 2.非父子组件或父子组件通过数据总数Bus,this.root.$emit('事件名',参数1,参数2,-) 3.非父子组件或父子组件 更好的方式是在vue中使用vuex 方法1: 用组件之间通讯.这样写很麻烦,并且写着写着,估计自己都不知道这是啥了,很容易写晕. 方法2: 我们定义全局变量.模块a的数据

  • Vue中的同步调用和异步调用方式

    目录 Vue的同步调用和异步调用 Promise实现异步调用 async /await方法实现同步调用 Vue同步和异步的问题 基本语法 实例 Vue的同步调用和异步调用 Promise实现异步调用 异步调用,增加a.b两个方法,并在mounted中调用. 观察客户端,并没有按照方法执行的顺序输出,使用Promise实现了异步调用. 观察客户端,并没有按照方法执行的顺序输出,使用Promise实现了异步调用. async /await方法实现同步调用 使用async 和 await配合promi

  • vue中promise的使用及异步请求数据的方法

    下面给大家介绍vue中promise的使用 promise是处理异步的利器,在之前的文章<ES6之promise>中,我详细介绍了promise的使用, 在文章<js动画实现&&回调地狱&&promise>中也提到了promise的then的链式调用, 这篇文章主要是介绍在实际项目中关于异步我遇到的一些问题以及解决方法,由此来加深对promise的进一步理解. 背景 进入商品页,商品页的左侧是分类,右侧是具体的商品,一旦进入商品页,就把所有分类的商品

  • vue中touch和click共存的解决方式

    在vue开发手机端项目时,我们经常会遇到touch和click共存的情况,比如城市选择页面的字母滑动 touch事件在手机端会触发浏览器滑动,所以应给touch事件添加阻止默认行为touchmove.prevent.注意阻止默认行为事件不要添加在touchstart事件上,会影响到click事件的发生. touch事件和click事件发生先后顺序: touchstart,touchmove,touchend,click 补充知识:touchstart与click同时触发 产生冲突的原因 我们可以

  • Vue中引入svg图标的两种方式

    Vue中引入svg图标的方式 Vue中引入svg图标的方式一 安装 yarn add svg-sprite-loader --dev svg组件 index.vue <!-- svg组件 --> <template> <svg class="svg-icon" :class="svgClass" aria-hidden="true"> <use :xlink:href="iconName&quo

  • 解析C#中委托的同步调用与异步调用(实例详解)

    委托的Invoke方法用来进行同步调用.同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行.同步调用的例子: 复制代码 代码如下: using System;using System.Threading;public delegate int AddHandler(int a, int b);public class Foo { static void Main() {  Console.WriteLine("**********SyncInvokeTest***

  • 同步调用和异步调用WebService

    异步,说到异步需要首先将以下同步.同步就是代码按照顺序执行,当前面的代码的请求没有正常返回结果的情况下,后面的代码是不能运行.而异步正好和这点不同,异步是代码运行后,不管当前的请求是否返回结果,后面的代码都会继续运行. 一:同步调用 一个同步操作会阻塞整个当前的进程,直到这个操作完成才能执行下一段代码 二:异步调用 不会阻塞启动操作的调用线程,调用程序必须通过轮流检测,或者等待完成信号来发现调用的完成 三:同步调用WebService 同步调用WebService就是我们平常的调用的写法 1:A

  • vue中data里面的数据相互使用方式

    目录 data里面的数据相互使用 具体代码如下 data里的数据不能相互引用问题 data里面的数据相互使用 今天在写代码的时候,遇到一个问题,我想使用data里面的一个对象使用data里面的某个数据,附图片: 我想让active的值给params对象里面的topicListType使用,我不想直接在一个方法里面改变这个值(想改的话就直接可以改了,太简单),所以就有了这个想法. 在data里面使用,但是肯定不能写成 this.params.topicListType: this.active,这

  • 在vue中使用eacharts创建graph关系图方式

    目录 使用eacharts创建graph关系图 vue中关系图组件 1.Graph.vue 2.GraphDemo.vue 使用eacharts创建graph关系图 在最近的工作中遇到了这个问题一开始遇到遇到问题且网上现在的教程不那么详细于是想着自己写一个来记录一下. 首先想使用echarts先下载echarts包命令如下 npm install echarts --save 然后将eacharts引入到项目中,推荐在main.js引入. import * as echarts from 'ec

  • Vue中定义全局变量与常量的各种方式详解

    前言 本文主要跟大家介绍了关于Vue定义全局变量与常量的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: 我想要定义一个变量, 在项目的任何地方都可以访问到, 不需要每一次使用的时候, 都引入. 尝试1: 创建 global.js 并且在其中定义 let a = 10; 在入口文件中引入 global.js import './global.js' 在项目中使用: a // 报错 发现报错了, a 并没有定义. 为什么? 这个涉及到模块作用域: 1 每一个 js 都相当于

随机推荐