当前位置:   article > 正文

面试题 async/await

面试题async await

async 

async 函数是 Generator 函数的语法糖。使用 关键字 async 来表示,在函数内部使用await 表明当前函数是异步函数 不会阻塞线程导致后续代码停止运行。
async function name([param[, param[, ... param]]]) { statements }复制代码

async 函数的返回值很特殊: 不管在函数体内 return 了什么值, async 函数的实际返回值总是一个 Promise 对象. 

详细讲就是:若在 async 函数中 return 了一个值 a, 不管 a 值是什么类型, async 函数的实际返回值总是 Promise.resolve(a)

  1. async function asyncFn() {
  2. return 'hello world';
  3. }
  4. console.log(asyncFn())
  5. //Promise {<resolved>: "hello world"}复制代码


由上可知 返回的是一个Promise对象

  1. async function asyncFn() {
  2. return 'hello world';
  3. }
  4. asyncFn()
  5. .then(res => {
  6. console.log(res)
  7. //hello world
  8. })复制代码
如果函数内部抛出异常或者是返回reject,都会使函数的promise状态为失败reject。
  1. async function asyncFn() {
  2. throw new Error('has Error');
  3. }
  4. asyncFn()
  5. .then(res => {
  6. console.log(res);
  7. })
  8. .catch(error => {
  9. console.log(error);
  10. })复制代码


await

await意思是async wait(异步等待)。这个关键字只能在使用async定义的函数里面使用。任何async函数都会默认返回promise,并且这个promise解析的值都将会是这个函数的返回值,而async函数必须等到内部所有的 await 命令的 Promise 对象执行完,才会发生状态改变


  1. async function getJsonAsync() {
  2. let result = await axios.get('api/user');
  3. return result
  4. }
  5. getJsonAsync()
  6. .then(function (res) {
  7. console.log(res.data)
  8. })
  9. .catch(function (error) {
  10. console.log(error)
  11. })复制代码

执行顺序解读

  1. console.log(1);
  2. async function asyncfn1(){
  3. console.log(2);
  4. await asyncfn2();
  5. console.log(3);
  6. };
  7. setTimeout(() => {
  8. console.log('setTimeout')
  9. }, 0)
  10. async function asyncfn2(){
  11. console.log(4)
  12. };
  13. asyncfn1();
  14. console.log(5);复制代码


分析:

  1. 打印 "1" 
  2. 遇到setTimeout,setTimeout是宏任务,将它放在宏任务队列中 执行 asyncfn1 打印 "2"
  3. 遇到await关键字,先执行关键字后面的 asyncfn2函数 打印:"4",因为await关键字将这块代码asyncContext挂起并执行上级 上下文 所以先打印了"5",执行完后回到 async context 打印 "3"  
  4. 最后打印 "setTimeout"


加入Promise

  1. async function async1(){
  2. console.log('async1 start')
  3. await async2()
  4. console.log('async1 end')
  5. }
  6. async function async2(){
  7. console.log('async2')
  8. }
  9. console.log('script start')
  10. setTimeout(function(){
  11. console.log('setTimeout')
  12. },0)
  13. async1();
  14. new Promise(function(resolve){
  15. console.log('promise1')
  16. resolve();
  17. }).then(function(){
  18. console.log('promise2')
  19. })
  20. console.log('script end')复制代码


重点:

  1. 执行到 await async2(),发现 async2 也是个 async 定义的函数,所以直接执行了“console.log('async2')”,同时async2返回了一个Promise,划重点:此时返回的Promise会被放入到回调队列中等待,await会让出线程(js是单线程还用我介绍吗),接下来就会跳出 async1函数 继续往下执行。
  2. 然后执行到 new Promise,前面说过了promise是立即执行的,所以先打印出来“promise1”,然后执行到 resolve 的时候,resolve这个任务就被放到回调队列中等待,然后跳出Promise继续往下执行,输出“script end”。 
  3. 同步的事件都循环执行完了,调用栈现在已经空出来了,那么事件循环就会去回调队列里面取任务继续放到调用栈里面了。

总结:

优先级: promise.Trick()>promise的回调>setTimeout>setImmediate


async/await 能代替Promise吗

使用Async / Await时,我们仍在使用Promise。从长远来看,对Promise的良好理解实际上对您有很大的好处。 甚至有一些用例Async / Await并不能解决问题,我们不得不回到Promise上 一个这样的场景


  1. const timeoutFn = function(value,timeout){
  2. return new Promise(function(resolve){
  3. return setTimeout(()=>{resolve(value)},timeout);
  4. });
  5. }
  6. async function getABC() {
  7. let A = await timeoutFn(2,2000); // 2 second to finish
  8. let B = await timeoutFn(2,2000); // 4 second to finish
  9. let C = await timeoutFn(3,3000); // 3 second to finish
  10. return A*B*C;
  11. }
  12. getABC()
  13. .then((res)=>{
  14. console.log(res)
  15. //12
  16. })复制代码

上述7秒之后输出12,因为三个变量A,B和C不相互依赖,每个调用将等待前一个返回结果

Promise.all()。这将允许我们同时发送所有请求。,但异步调用将并行触发,而不是一个接一个地触发,3秒之后返回借过12

  1. const timeoutFn = function(value,timeout){
  2. return new Promise(function(resolve){
  3. return setTimeout(()=>{resolve(value)},timeout);
  4. });
  5. }
  6. async function getABC() {
  7. // Promise.all()允许我们同时发送所有请求。
  8. let results = await Promise.all([ timeoutFn(2,2000), timeoutFn(2,2000), timeoutFn(3,3000) ]);
  9. return results.reduce((total,value) => total * value);
  10. }
  11. getABC()
  12. .then(res => {
  13. console.log(res)
  14. //12
  15. })复制代码


转载于:https://juejin.im/post/5ca9e4356fb9a05e3d0a8a35

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/555100
推荐阅读
相关标签
  

闽ICP备14008679号