前言 我们经常会遇到这样的麻烦事,多个函数按顺序执行,返回结果却不是我们预期的顺序,原因一般是由于异步操作引起的,所以呢,我们需要一种解决方案来处理这种问题,从而使得异步操作按照同步的方式来执行,这样我们就可以控制异步操作输出结果的顺序了
异步操作会带来什么问题 异步操作可能会许多的问题,下面是常见的两种
1.函数执行的结果并不是按照顺序返回 1 2 3 4 5 6 7 8 9 10 11 12 function fn1 ( ){ console .log (111 ) setTimeout (function ( ){ console .log ('wait me 3000' ) },3000 ) } function fn2 ( ){ console .log (222 ) } fn1 ();fn2 ();
上面的代码,如果你期待的结果是
那就错了,因为fn1
函数里面还有一个函数setTimeout
,这两个函数是异步执行的,而fn1
和fn2
是同步执行的,先执行fn1
再执行fn2
,在执行fn1
的时候打印结果111
,三秒后再执行setTimeout
,但是在这三秒之前已经执行完了fn2
2.在外部获取不到异步函数里的值 下面我们看一个最简单的例子,我的需求是要在fn1
函数外面打印msg
1 2 3 4 5 6 function fn1 ( ){ setTimeout (function ( ){ msg='wait me 3000' ; },3000 ); } fn1 ();
那么怎么样才能获取到msg
呢
使用回调函数 1 2 3 4 5 6 7 8 9 function fn1 (callback ){ setTimeout (function ( ){ msg='wait me 3000' ; callback (msg); },3000 ); } fn1 (data => { console .log (data); });
使用Promise 1 2 3 4 5 6 7 8 9 10 11 function fn1 ( ){ return new Promise (function (res,rej ){ setTimeout (function ( ){ msg='wait me 3000' ; res (msg); },3000 ); }) } fn1 ().then (data => { console .log (data) })
关于Promise
的信息可以参考
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
async/await解决方案 async/await的作用就是使异步操作以同步的方式去执行
异步操作同步化?
可以使用Promise中的then()来实现,那么async/await与它之间有什么区别呢
1.async函数返回的是一个Promise对象 如果一个函数加了async
关键词,这个函数又有返回值,在调用这个函数时,如果函数执行成功,内部会调用Promise.solve()
方法返回一个Promise
对象,如果函数执行出现异常,就会调用Promise.reject()
方法返回一个promise
对象
要想获取到async
函数的执行结果,就要调用Promise
的then
或catch
来给它注册回调函数
1 2 3 4 async function fn ( ){ return '111' } console .log (fn ());
既然是Promise
对象,因此可以使用then()
获取返回的结果
1 2 3 4 5 6 async function fn ( ){ return '111' } fn ().then (data => { console .log (data) })
2.await 上面介绍了async
的作用,一般情况下,async
与await
配合使用才能使异步操作同步化,await
就是等待的意思,等待某一个函数执行完之后,后面的代码才能开始执行
1 2 3 4 5 6 7 8 9 10 11 12 13 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
总结 aysnc await
可以让我们以同步的方式编写异步代码
在很多的时候,我们是希望按照同步的方式来获得异步函数的结果,比如登录时,我们必须要在后台返回匹配成功的信息之后才能进行页面跳转,因此,使异步操作同步化这是很重要的知识点,但是这种方案是基于Promise
的基础之上的,因此在学习该知识时,一定要对Promise
有充分的理解
参考链接
https://juejin.cn/post/6844903984889593863