async/await让异步操作同步执行的方法详解
一.前言
我们经常会遇到这样的麻烦事,多个函数按顺序执行,返回结果却不是我们预期的顺序,原因一般是由于异步操作引起的,所以呢,我们需要一种解决方案来处理这种问题,从而使得异步操作按照同步的方式来执行,这样我们就可以控制异步操作输出结果的顺序了
二.异步操作会带来什么问题
异步操作可能会许多的问题,下面是常见的两种
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有充分的理解
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。
您可能感兴趣的文章:
- 利用AsyncCallback将同步方法转为异步执行
- 利用AsyncCallback将同步方法转为异步执行
- 使用async和await将同步方法包装成异步方法
- 使用Promise和async-await实现的一个异步遍历+同步执行任务的实例
- 利用async和await异步操作解决node.js里面fs模块异步读写,同步结果的问题
- async await 同步方法调用异步方法死锁
- 微信小程序中使用Async-await方法异步请求变为同步请求方法
- 关于异步执行(async)与异步等待(await)
- 同步异步的理解 (async/await)
- 异步的查询操作帮助类 AsyncQueryHandler 详解
- [.NET] 利用 async & await 进行异步 IO 操作
- .NET Core控制台应用程序如何使用异步(Async)Main方法详解
- .NET/C# 使用async和await关键字调用异步方法
- asp.net webform中使用async,await实现异步操作
- async/await与promise(nodejs中的异步操作问题)
- BroadcastReceiver 使用goAsync 执行异步操作
- javaScript中的同步和异步解析,以及用async函数,promise优美地完成异步操作
- async/await通过”同步“实现异步
- ES7之async/await 同步还是异步
- 多线程GCD+同步执行+异步执行+并行执行+串行执行+重复、分组、延迟、障碍方法