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 相关文章推荐
fancybox1.3.1 基于Jquery的插件在IE中图片显示问题
Oct 01 Javascript
artDialog双击会关闭对话框的修改过程分享
Aug 05 Javascript
jQuery异步加载数据并添加事件示例
Aug 24 Javascript
如何解决ligerUI布局时Center中的Tab高度大小
Nov 24 Javascript
推荐三款不错的图片压缩上传插件(webuploader、localResizeIMG4、LUploader)
Apr 21 Javascript
(模仿京东用户注册)用JQuery实现简单表单验证,初学者必看
Jan 08 jQuery
Angular5集成eventbus的示例代码
Jul 19 Javascript
详解微信JS-SDK选择图片遇到的坑
Aug 15 Javascript
css配合JavaScript实现tab标签切换效果
Oct 11 Javascript
vue语法自动转typescript(解放双手)
Sep 18 Javascript
js实现html滑动图片拼图验证
Jun 24 Javascript
吃通javascript正则表达式
Apr 21 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 字符串编码截取函数(兼容utf-8和gb2312)
2009/05/02 PHP
PHP使用DOMDocument类生成HTML实例(包含常见标签元素)
2014/06/25 PHP
php header函数的常用http头设置
2015/06/25 PHP
PHP切割汉字的常用方法实例总结
2019/04/27 PHP
一些易混淆且不常用的属性,希望有用
2007/01/29 Javascript
jquery 锁定弹出层实现代码
2010/02/23 Javascript
从js向Action传中文参数出现乱码问题的解决方法
2013/12/29 Javascript
Javascript基础知识(一)核心基础语法与事件模型
2014/09/29 Javascript
js设置和获取自定义属性的方法
2016/10/20 Javascript
JS jQuery使用正则表达式去空字符的简单实现代码
2017/05/20 jQuery
解决JS外部文件中文注释出现乱码问题
2017/07/09 Javascript
React根据宽度自适应高度的示例代码
2017/10/11 Javascript
vue一个页面实现音乐播放器的示例
2018/02/06 Javascript
JS字符串去除连续或全部重复字符的实例
2018/03/08 Javascript
webpack4 升级迁移的实现
2018/09/12 Javascript
ES6基础之解构赋值(destructuring assignment)
2019/02/21 Javascript
浅谈react-router@4.0 使用方法和源码分析
2019/06/04 Javascript
js类的继承定义与用法分析
2019/06/21 Javascript
node使用mysql获取数据库数据中文乱码问题的解决
2019/12/02 Javascript
Vue实现Layui的集成方法步骤
2020/04/10 Javascript
[01:08]2014DOTA2展望TI 剑指西雅图LGD战队专访
2014/06/30 DOTA
[01:24]DOTA2上海特锦赛OG战队抵达 专车接机入驻总统套房
2016/02/23 DOTA
简要讲解Python编程中线程的创建与锁的使用
2016/02/28 Python
Python实现程序判断季节的代码示例
2019/01/28 Python
详解Pycharm出现out of memory的终极解决方法
2020/03/03 Python
台湾最大银发乐活百货:乐龄网
2018/05/21 全球购物
个人能力自我鉴赏
2014/01/25 职场文书
财务简历的自我评价
2014/03/05 职场文书
财务负责人任命书
2014/06/06 职场文书
小学生感恩父母演讲稿
2014/08/28 职场文书
消防演习通知
2015/04/25 职场文书
无工作证明怎么写
2015/06/15 职场文书
学长教您写论文:经验总结
2019/07/09 职场文书
html实现随机点名器的示例代码
2021/04/02 Javascript
python中的random模块和相关函数详解
2022/04/22 Python
python神经网络 使用Keras构建RNN训练
2022/05/04 Python