博学谷学习记录 | 学习总结,用心分享 | 前端学习之Ajax(四)

文章介绍了如何使用async和await来解决回调地狱问题,使异步代码更加结构化。async函数让异步操作变得更为简洁,await用于等待Promise解析,使得代码看起来更像同步执行。同时,文章提到了JavaScript的单线程特性和事件循环队列的概念,包括宏任务和微任务的执行顺序,帮助理解异步代码的执行流程。
摘要由CSDN通过智能技术生成

1 async 和 await

首先,我们来回顾一下能够解决“回调地狱”的 Promise 对象及其用法。

  <script>
    new Promise((resolve,reject)=>{
      setTimeout(() => {
        resolve('red')
      }, 2000);
    }).then((res)=>{
      console.log(res);
      return new Promise((resolve,reject)=>{
        setTimeout(() => {
          resolve('yellow')
        }, 1000);
      })
    }).then((res)=>{
      console.log(res);
      return new Promise((resolve,reject)=>{
        setTimeout(() => {
          resolve('green')
        }, 3000);
      })
    }).then((res)=>{
      console.log(res);
      return new Promise((resolve,reject)=>{
        setTimeout(() => {
          resolve('ok1')
        }, 2000);
      })
    }).then((res)=>{
      console.log(res);
      return new Promise((resolve,reject)=>{
        setTimeout(() => {
          resolve('ok2')
        }, 1000);
      })
    }).then((res)=>{
      console.log(res);
      return new Promise((resolve,reject)=>{
        setTimeout(() => {
          resolve('ok3')
        }, 3000);
      })
    }).then((res)=>{
      console.log(res);
    })
  </script>

使用 Promise 对象消除“回调地狱”时利用了“链式编程”,这种方式虽然比回调嵌套更具有可读性和可维护性,但是长长的一连串代码仍然让人觉得有些头疼,和印象中的“结构化编程”有点搭不上边儿。

如果能让每个 new Promise() 都分开执行,变成单独的一或两行代码,那么在观感上就变成了我们非常熟悉的“结构化编程”的样子,我们只需要利用 async 和 await 就能做到这一点。

1.async 和 await 的基本使用

(1)async 用于修饰一个函数, 表示该函数为异步函数,
(2)await 为 async 函数内的关键字,它仅仅作为一个标记,表示其后紧接的代码为异步代码,           如果 async 函数内没有 await,也就是说其内部全是同步代码,则 async 无意义,而 await             也只能用在 async 函数中,单独使用会报错。
(3)await 后面一般会跟一个 Promise 对象,await 会阻塞 async 函数的执行,直到 Promise                 成功执行后(resolve的结果)才会继续执行后续代码。
(4)await 只会等待 Promise 成功的结果,如果失败了则会报错(这种情况就需要使用 try                     catch)。

    <script>
        async function fn() {
            try {
                let { data: res } = await axios.get('http://www.xxx.top:3006/api/getbooks')
                console.log(res) // axios请求成功则会打印请求结果
            } catch (e) {
                console.log(e) // axios请求失败则会打印错误消息
            }
        }
        fn()
    </script>

2.async 和 await 解决“回调地狱”问题

    <script>
        // 使用 async await 解决回调地狱问题

        async function solveFn(){
            await new Promise((resolve,reject)=>{
                setTimeout(() => {
                    resolve('red')
                }, 2000);
                }).then((res)=>{
                console.log(res);
            })
            await new Promise((resolve,reject)=>{
                setTimeout(() => {
                    resolve('yellow')
                }, 1000);
                }).then((res)=>{
                console.log(res);
            })
            await new Promise((resolve,reject)=>{
                setTimeout(() => {
                    resolve('green')
                }, 3000);
                }).then((res)=>{
                console.log(res);
            })
            await new Promise((resolve,reject)=>{
                setTimeout(() => {
                    resolve('ok1')
                }, 2000);
                }).then((res)=>{
                console.log(res);
            })
            await new Promise((resolve,reject)=>{
                setTimeout(() => {
                    resolve('ok2')
                }, 1000);
                }).then((res)=>{
                console.log(res);
            })
            await new Promise((resolve,reject)=>{
                setTimeout(() => {
                    resolve('ok3')
                }, 3000);
                }).then((res)=>{
                console.log(res);
            })
        }
        solveFn()
    </script>

 与“链接编程”相比,上面的代码更符合“结构化编程”的习惯,而且还能达到同样的效果。

2 事件循环队列 

由于 JavaScript 是一门单线程执行的编程语言,也就是同一时间只能做一件事情,因此会遇到假如前一个任务非常耗时,那么后续任务就不得不一直等待的情况。为了防止某个耗时任务导致程序假死的问题,JavaScript 会将异步代码委托给宿主环境(node环境, 浏览器)等待执行。

 下面是一张任务执行图,

 图中的宏任务是指诸如主代码块、setTimeout、setInterval之类的代码,它们都有一个共同的特点,就是上一个执行完毕后才会考虑执行下一个;微任务是指诸如 promise.then、promise.catch之类的代码,它们会在当前宏任务执行完毕,下一个宏任务开始前执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值