async/await让异步操作同步执行的方法详解


Posted in Javascript onNovember 01, 2019

一.前言

我们经常会遇到这样的麻烦事,多个函数按顺序执行,返回结果却不是我们预期的顺序,原因一般是由于异步操作引起的,所以呢,我们需要一种解决方案来处理这种问题,从而使得异步操作按照同步的方式来执行,这样我们就可以控制异步操作输出结果的顺序了

二.异步操作会带来什么问题

异步操作可能会许多的问题,下面是常见的两种

1.函数执行的结果并不是按照顺序返回

function fn1(){
 console.log(111)
 setTimeout(function(){
  console.log('wait me 3000')
 },3000)
}
function fn2(){
 console.log(222)
}
fn1();
fn2();

//结果
//111
//222
//wait me 3000

上面的代码,如果你期待的结果是

//111
//wait me 3000
//222

那就错了,因为fn1函数里面还有一个函数setTimeout,这两个函数是异步执行的,而fn1和fn2是同步执行的,先执行fn1再执行fn2,在执行fn1的时候打印结果111,三秒后再执行setTimeout,但是在这三秒之前已经执行完了fn2

那是不是由于setTimeout函数设置的等待时间太久了才会导致的呢?那下面我把时间设为0

function fn1(){
 console.log(111)
 setTimeout(function(){
  console.log('wait me 3000')
 },0)
}
function fn2(){
 console.log(222)
}
fn1();
fn2();
//结果
//111
//222
//wait me 3000

从结果上看并没有改变,这是应为setTimeout这个函数在执行之前会查看执行队列看看有没有人在排队,如果有,那么将等其他的函数执行完再执行自己,所以不管就算你设置时间为0,也不会改变它最后一个执行

2.在外部获取不到异步函数里的值

下面我们看一个最简单的例子,我的需求是要在fn1函数外面打印msg

function fn1(){
 setTimeout(function(){
  msg='wait me 3000';
 },3000);
}
fn1();

那么怎么样才能获取到msg呢

使用回调函数

function fn1(callback){
 setTimeout(function(){
  msg='wait me 3000';
  callback(msg);
 },3000);
}
fn1(data=>{
 console.log(data);//wait me 3000
});

使用Promise

function fn1(){
 return new Promise(function(res,rej){
  setTimeout(function(){
   msg='wait me 3000';
   res(msg);
  },3000);
 })
}
fn1().then(data=>{
 console.log(data)
})

三.async/await解决方案

async/await的作用就是使异步操作以同步的方式去执行

异步操作同步化?

可以使用Promise中的then()来实现,那么async/await与它之间有什么区别呢

1.async函数返回的是一个Promise对象

如果一个函数加了async关键词,这个函数又有返回值,在调用这个函数时,如果函数执行成功,内部会调用Promise.solve()方法返回一个Promise对象,如果函数执行出现异常,就会调用Promise.reject()方法返回一个promise 对象

要想获取到async函数的执行结果,就要调用Promise的then或catch来给它注册回调函数

async function fn(){
 return '111'
}
console.log(fn());//Promise { '111' }

既然是Promise对象,因此可以使用then()获取返回的结果

async function fn(){
 return '111'
}
fn().then(data=>{
 console.log(data)//111
})

2.await

上面介绍了async的作用,一般情况下,async与await配合使用才能使异步操作同步化,await就是等待的意思,等待某一个函数执行完之后,后面的代码才能开始执行

function fn1(){
 return new Promise(resolve=>{
  setTimeout(function(){
   msg='wait me 3000';
   resolve(msg)
  },3000);
 });
}
async function asyncCall(){
 var result=await fn1();
 console.log(result); 
}
asyncCall();

如果我们没有等待fn1执行完之后再打印result,那么有可能得到是undefined

四.总结

在很多的时候,我们是希望按照同步的方式来获得异步函数的结果,比如登录时,我们必须要在后台返回匹配成功的信息之后才能进行页面跳转,因此,使异步操作同步化这是很重要的知识点,但是这种方案是基于Promise的基础之上的,因此在学习该知识时,一定要对Promise有充分的理解

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
学习YUI.Ext第七日-View&JSONView Part Two-一个画室网站的案例
Mar 10 Javascript
Javascript 的addEventListener()及attachEvent()区别分析
May 21 Javascript
Juqery Html(),append()等方法的Bug解决方法
Dec 13 Javascript
Jquery 自定义动画概述及示例
Mar 29 Javascript
IE、FF、Chrome浏览器中的JS差异介绍
Aug 13 Javascript
javascript的数组和常用函数详解
May 09 Javascript
node.js中的fs.existsSync方法使用说明
Dec 17 Javascript
JavaScript实现当网页加载完成后执行指定函数的方法
Mar 21 Javascript
基于LayUI分页和LayUI laypage分页的使用示例
Aug 02 Javascript
js实现轮播图的完整代码
Oct 26 Javascript
Vue入门学习笔记【基本概念、对象、过滤器、指令等】
Apr 13 Javascript
Vue简单实现原理详解
May 07 Javascript
浅谈Three.js截图并下载的大坑
Nov 01 #Javascript
vue中使用vee-validator完成表单校验方案
Nov 01 #Javascript
解决vue的过渡动画无法正常实现问题
Oct 31 #Javascript
VUE单页面切换动画代码(全网最好的切换效果)
Oct 31 #Javascript
js new Date()实例测试
Oct 31 #Javascript
一起写一个即插即用的Vue Loading插件实现
Oct 31 #Javascript
Vue 使用beforeEach实现登录状态检查功能
Oct 31 #Javascript
You might like
php学习之变量的使用
2011/05/29 PHP
PHP查询数据库中满足条件的记录条数(两种实现方法)
2013/01/29 PHP
php中get_object_vars()方法用法实例
2015/02/08 PHP
完美解决在ThinkPHP控制器中命名空间的问题
2017/05/05 PHP
Jquery使用val方法读写value值
2015/05/18 Javascript
AngularJS转换响应内容
2016/01/27 Javascript
jQuery简单实现上下,左右滑动的方法
2016/06/01 Javascript
初识简单却不失优雅的Vue.js
2016/09/12 Javascript
微信小程序 动画的简单实例
2017/10/12 Javascript
微信小程序基于本地缓存实现点赞功能的方法
2017/12/18 Javascript
jQuery动态移除与增加onclick属性的方法详解
2018/06/07 jQuery
Node.js 使用axios读写influxDB的方法示例
2018/10/26 Javascript
vue  directive定义全局和局部指令及指令简写
2018/11/20 Javascript
Vue在H5 项目中使用融云进行实时个人单聊通讯
2020/12/14 Vue.js
[01:19:46]DOTA2-DPC中国联赛 正赛 SAG vs DLG BO3 第一场 2月28日
2021/03/11 DOTA
python使用7z解压apk包的方法
2015/04/18 Python
Linux下用Python脚本监控目录变化代码分享
2015/05/21 Python
Python实现的读写json文件功能示例
2018/06/05 Python
目前最全的python的就业方向
2018/06/05 Python
python实现自动发送邮件
2018/06/20 Python
python爬虫之自动登录与验证码识别
2020/06/15 Python
详解python 降级到3.6终极解决方案
2020/02/06 Python
Python实现手绘图效果实例分享
2020/07/22 Python
Python如何使用input函数获取输入
2020/08/06 Python
python压包的概念及实例详解
2021/02/17 Python
柯基袜:Corgi Socks
2017/01/26 全球购物
美国电视购物:QVC
2017/02/06 全球购物
MAC Cosmetics巴西官方网站:M·A·C彩妆
2019/04/18 全球购物
英国领先的在线高尔夫设备零售商:Golfgeardirect
2020/12/11 全球购物
电子商务专业自我鉴定
2013/12/18 职场文书
社区文明倡议书
2015/04/28 职场文书
公司处罚决定书
2015/06/24 职场文书
关于vue中如何监听数组变化
2021/04/28 Vue.js
解决pytorch-gpu 安装失败的记录
2021/05/24 Python
Win11运行育碧游戏总是崩溃怎么办 win11玩育碧游戏出现性能崩溃的解决办法
2022/04/06 数码科技
Redis过期数据是否会被立马删除
2022/07/23 Redis