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 相关文章推荐
对联广告js flash激活
Oct 19 Javascript
利用javascript实现全部删或清空所选的操作
May 27 Javascript
JavaScript实现简单的二级导航菜单实例
Apr 15 Javascript
js 获取经纬度的实现方法
Jun 20 Javascript
js控制台输出的方法(详解)
Nov 26 Javascript
canvas 画布在主流浏览器中的尺寸限制详细介绍
Dec 15 Javascript
基于Angularjs+mybatis实现二级评论系统(仿简书)
Feb 13 Javascript
JavaScript实现职责链模式概述
Jan 25 Javascript
JavaScript实现新年倒计时效果
Nov 17 Javascript
详解Js里的for…in和for…of的用法
Mar 28 Javascript
Vue3项目打包后部署到服务器 请求不到后台接口解决方法
Feb 06 Javascript
jquery检测上传文件大小示例
Apr 26 jQuery
浅谈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程序--记数器
2006/10/09 PHP
Memcache 在PHP中的使用技巧
2010/02/08 PHP
php数组函数序列之in_array() 查找数组值是否存在
2011/10/29 PHP
克隆javascript对象的三个方法小结
2011/01/12 Javascript
图片上传判断及预览脚本的效果实例
2013/08/07 Javascript
JavaScript之数组(Array)详解
2015/04/01 Javascript
js下拉选择框与输入框联动实现添加选中值到输入框的方法
2015/08/17 Javascript
JavaScript编写点击查看大图的页面半透明遮罩层效果实例
2016/05/09 Javascript
EasyUI在表单提交之前进行验证的实例代码
2016/06/24 Javascript
jQuery 中msgTips 顶部弹窗效果实现代码
2017/08/14 jQuery
jquery 实现拖动文件上传加载进度条功能
2018/03/18 jQuery
微信小程序实现tab左右切换效果
2020/11/15 Javascript
Vue开发之watch监听数组、对象、变量操作分析
2019/04/25 Javascript
VSCode使用之Vue工程配置eslint
2019/04/30 Javascript
微信小程序实现点击图片放大预览
2019/10/21 Javascript
基于JavaScript实现十五拼图代码实例
2020/04/26 Javascript
express异步函数异常捕获示例详解
2020/11/30 Javascript
[06:59]DOTA2-DPC中国联赛3月7日Recap集锦
2021/03/11 DOTA
Python实现二叉树结构与进行二叉树遍历的方法详解
2016/05/24 Python
python绘制铅球的运行轨迹代码分享
2017/11/14 Python
Python面向对象类的继承实例详解
2018/06/27 Python
详解Django+uwsgi+Nginx上线最佳实战
2019/03/14 Python
python中PS 图像调整算法原理之亮度调整
2019/06/28 Python
一款基于css3和jquery实现的动画显示弹出层按钮教程
2015/01/04 HTML / CSS
中国第一家杂志折扣订阅网:杂志铺
2016/08/30 全球购物
亚马逊意大利站点:Amazon.it
2020/12/31 全球购物
公司年会搞笑主持词
2014/03/24 职场文书
董事长助理工作职责
2014/06/08 职场文书
关于感恩的演讲稿500字
2014/08/26 职场文书
创先争优演讲稿
2014/09/15 职场文书
教师作风建设剖析材料
2014/10/11 职场文书
招商引资工作汇报
2014/10/28 职场文书
处级干部考察材料
2014/12/24 职场文书
讲座开场白台词和结束语
2015/05/29 职场文书
海底两万里读书笔记
2015/06/26 职场文书
解析原生JS getComputedStyle
2021/05/25 Javascript