ES7之Async/await的使用详解


Posted in Javascript onMarch 28, 2019

在 js 异步请求数据时,通常,我们多采用回调函数的方式解决,但是,如果有多个回调函数嵌套时,代码显得很不优雅,维护成本也相应较高。 ES6 提供的 Promise 方法和 ES7 提供的 Async/Await 语法糖可以更好解决多层回调问题。

Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及其返回的值。
await 操作符用于等待一个Promise 对象。它只能在异步函数 async function 中使用。
await 表达式会暂停当前 async function 的执行,等待 Promise 处理完成。若 Promise 正常处理(fulfilled),其回调的resolve函数参数作为 await 表达式的值,继续执行 async function。

一个ajax请求时

通常 使用 ajax 请求数据时,会

$.ajax({
 url: 'data1.json',
 type: 'GET',
 success: function (res) {
  console.log(res) // 请求成功,则得到结果res
 },
 error: function(err) {
  console.log(err)
 }
})

上面可以得到我们想要的结果 res ---> { "url": "data2.json" }

多个ajax请求时

但是 当得到的数据 res 需要用于另一个 ajax 请求时,则需要如下写法:

$.ajax({
 url: 'data1.json',
 type: 'GET',
 success: function (res) {
  $.ajax({
   url: res.url, // 将 第一个ajax请求成功得到的res 用于第二个ajax请求
   type: 'GET',
   success: function (res) {
    $.ajax({
     url: res.url, // 将第二个ajax请求成功得到的res 用于第三个ajax请求
     type: 'GET',
     success: function (res) {
      console.log(res) // {url: "this is data3.json"}
     },
     error: function(err) {
      console.log(err)
     }
    })
   },
   error: function(err) {
    console.log(err)
   }
  })
 },
 error: function(err) {
  console.log(err)
 }
})

上面出现多个回调函数的嵌套,可读性较差(虽然这种嵌套在平常的开发中少见,但是在node服务端开发时,还是很常见的)

优化方法

使用 promise 链式操作

如下,使用 Promise,进行链式操作,可以使上面的异步代码看起来如同步般易读,从回调地狱中解脱出来。。

function ajaxGet (url) {
 return new Promise(function (resolve, reject) {
  $.ajax({
   url: url,
   type: 'GET',
   success: function (res) {
    resolve(res);
   },
   error: function(err) {
    reject('请求失败');
   }
  })
 })
};

ajaxGet('data1.json').then((d) => {
 console.log(d);  // {url: "data2.json"}
 return ajaxGet(d.url);
}).then((d) => {
 console.log(d);  // {url: "data3.json"}
 return ajaxGet(d.url);
}).then((d) => {
 console.log(d);  // {url: "this is data3.json"}
})

Async/await 方法

  • async 表示这是一个async函数,即异步函数,await只能用在这个函数里面。
  • await 表示在这里等待promise返回结果了,再继续执行。
  • await 后面跟着的应该是一个promise对象(当然,其他返回值也没关系,只是会立即执行,不过那样就没有意义了…)
  • await 操作符用于等待一个Promise 对象。它只能在异步函数 async function 中使用。
  • await 等待的虽然是promise对象,但不必写.then(..),直接可以得到返回值。

执行一个ajax请求,可以通过如下方法:

function ajaxGet (url) {
 return new Promise(function (resolve, reject) {
  $.ajax({
   url: url,
   type: 'GET',
   success: function (res) {
    resolve(res)
   },
   error: function(err) {
    reject('请求失败')
   }
  })
 })
};

async function getDate() {
 console.log('开始')
 let result1 = await ajaxGet('data1.json');
 console.log('result1 ---> ', result1); // result1 ---> {url: "data2.json"}
};
getDate();  // 需要执行异步函数

执行多个ajax请求时:

function ajaxGet (url) {
 return new Promise(function (resolve, reject) {
  $.ajax({
   url: url,
   type: 'GET',
   success: function (res) {
    resolve(res)
   },
   error: function(err) {
    reject('请求失败')
   }
  })
 })
};

async function getDate() {
 console.log('开始')
 let result1 = await ajaxGet('data1.json');
 let result2 = await ajaxGet(result1.url);
 let result3 = await ajaxGet(result2.url);
 console.log('result1 ---> ', result1); // result1 ---> {url: "data2.json"}
 console.log('result2 ---> ', result2); // result2 ---> {url: "data3.json"}
 console.log('result3 ---> ', result3); // result3 ---> {url: "this is data3.json"}
};

getDate(); // 需要执行异步函数

async await捕捉错误:

async await中.then(..)不用写了,那么.catch(..)也不用写,可以直接用标准的try catch语法捕捉错误。

例如,如果下面的 url 写错了

function ajaxGet (url) {
 return new Promise(function (resolve, reject) {
  $.ajax({
   url: url111, // 此处为错误的 url
   type: 'GET',
   success: function (res) {
    resolve(res)
   },
   error: function(err) {
    reject('请求失败')
   }
  })
 })
};


async function getDate() {
 console.log('开始')
 try {
  let result1 = await ajaxGet('data1.json'); // 执行到这里报错,直接跳至下面 catch() 语句
  let result2 = await ajaxGet(result1.url);
  let result3 = await ajaxGet(result2.url);
  console.log('result1 ---> ', result1);
  console.log('result2 ---> ', result2);
  console.log('result3 ---> ', result3);

 } catch(err) {
  console.log(err) // ReferenceError: url111 is not defined
 }
};

getDate(); // 需要执行异步函数

源码

源码查看

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
利用jQuery操作对象数组的实现代码
Apr 27 Javascript
JavaScript高级程序设计阅读笔记(六) ECMAScript中的运算符(二)
Feb 27 Javascript
jQuery监控文本框事件并作相应处理的方法
Apr 16 Javascript
深入浅析JavaScript中的Function类型
Jul 09 Javascript
JS实现数字格式千分位相互转换方法
Aug 01 Javascript
vue.js入门教程之基础语法小结
Sep 01 Javascript
vue日期组件 支持vue1.0和2.0
Jan 09 Javascript
基于JavaScript实现的希尔排序算法分析
Apr 14 Javascript
vue中计算属性(computed)、methods和watched之间的区别
Jul 27 Javascript
Vue 中批量下载文件并打包的示例代码
Nov 20 Javascript
基于Vue、Vuex、Vue-router实现的购物商城(原生切换动画)效果
Jan 09 Javascript
微信小程序之多列表的显示和隐藏功能【附源码】
Aug 06 Javascript
详解vue-cli3多环境打包配置
Mar 28 #Javascript
微信小程序之onLaunch与onload异步问题详解
Mar 28 #Javascript
详解vue使用插槽分发内容slot的用法
Mar 28 #Javascript
详解一个基于套接字实现长连接的express
Mar 28 #Javascript
微信小程序学习笔记之跳转页面、传递参数获得数据操作图文详解
Mar 28 #Javascript
微信小程序学习笔记之表单提交与PHP后台数据交互处理图文详解
Mar 28 #Javascript
深入理解es6块级作用域的使用
Mar 28 #Javascript
You might like
php获取某个目录大小的代码
2008/09/10 PHP
CI框架学习笔记(二) -入口文件index.php
2014/10/27 PHP
阿里云Win2016安装Apache和PHP环境图文教程
2018/03/11 PHP
php array_map()函数实例用法
2021/03/03 PHP
JavaScript 事件查询综合
2009/07/13 Javascript
js中判断控件是否存在
2010/08/25 Javascript
js控制多图左右滚动切换效果代码分享
2015/08/26 Javascript
jquery判断当前浏览器的实现代码
2015/11/07 Javascript
js实现模拟银行卡账号输入显示效果
2015/11/18 Javascript
js改变style样式和css样式的简单实例
2016/06/28 Javascript
HTML5+JS+JQuery+ECharts实现异步加载问题
2017/12/16 jQuery
通过jquery的ajax请求本地的json文件方法
2018/08/08 jQuery
python使用点操作符访问字典(dict)数据的方法
2015/03/16 Python
python如何把嵌套列表转变成普通列表
2018/03/20 Python
python实现机器学习之多元线性回归
2018/09/06 Python
在python plt图表中文字大小调节的方法
2019/07/08 Python
详解Python打包分发工具setuptools
2019/08/05 Python
python获取Pandas列名的几种方法
2019/08/07 Python
对django的User模型和四种扩展/重写方法小结
2019/08/17 Python
python 经典数字滤波实例
2019/12/16 Python
Python利用PyExecJS库执行JS函数的案例分析
2019/12/18 Python
python实现百度OCR图片识别过程解析
2020/01/17 Python
新建文件时Pycharm中自动设置头部模板信息的方法
2020/04/17 Python
Python绘制全球疫情变化地图的实例代码
2020/04/20 Python
python读取hdfs上的parquet文件方式
2020/06/06 Python
python实现画图工具
2020/08/27 Python
Python使用Turtle模块绘制国旗的方法示例
2021/02/28 Python
html5 touch事件实现触屏页面上下滑动(一)
2016/03/10 HTML / CSS
浅析HTML5页面元素及属性
2021/01/20 HTML / CSS
Hotels.com台湾:饭店订房网
2017/09/06 全球购物
金融管理专业毕业生求职信
2014/03/12 职场文书
工商行政管理专业求职书
2014/05/23 职场文书
群众路线领导班子整改方案
2014/10/25 职场文书
敬业奉献模范事迹材料
2014/12/24 职场文书
小学公民道德宣传日活动总结
2015/03/23 职场文书
如何让你的Nginx支持分布式追踪详解
2022/07/07 Servers