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 选择器、DOM操作、事件、动画
Nov 25 Javascript
jQuery中jqGrid分页实现代码
Nov 04 Javascript
jQuery Tools tab(幻灯片)
Jul 14 Javascript
js如何判断用户是否是用微信浏览器
Jun 05 Javascript
Javascript非构造函数的继承
Apr 27 Javascript
学习vue.js中class与style绑定
Dec 03 Javascript
bootstrap multiselect 多选功能实现方法
Jun 05 Javascript
微信小程序的分类页面制作
Jun 27 Javascript
最新Javascript程序员面试试题和解题方法
Nov 23 Javascript
发布订阅模式在vue中的实际运用实例详解
Jun 09 Javascript
angular6开发steps步骤条组件
Jul 04 Javascript
layui表格设计以及数据初始化详解
Oct 26 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判断两个浮点数是否相等的方法
2015/03/14 PHP
php遍历CSV类实例
2015/04/14 PHP
自适应高度框架 ----属个人收藏内容
2007/01/22 Javascript
js获取input标签的输入值实现代码
2013/08/05 Javascript
jQuery 属性选择器element[herf*='value']使用示例
2013/10/20 Javascript
微信浏览器内置JavaScript对象WeixinJSBridge使用实例
2015/05/25 Javascript
JS响应鼠标点击实现两个滑块区间拖动效果
2015/10/26 Javascript
js判断登陆用户名及密码是否为空的简单实例
2016/05/16 Javascript
JS实现星星评分功能实例代码(两种方法)
2016/06/09 Javascript
《javascript少儿编程》location术语总结
2018/05/27 Javascript
vue 动态组件用法示例小结
2020/03/06 Javascript
Ant Design Vue table中列超长显示...并加提示语的实例
2020/10/31 Javascript
Nodejs实现微信分账的示例代码
2021/01/19 NodeJs
javascript实现倒计时关闭广告
2021/02/09 Javascript
Python中字符串对齐方法介绍
2015/05/21 Python
Python自动化部署工具Fabric的简单上手指南
2016/04/19 Python
详解Golang 与python中的字符串反转
2017/07/21 Python
python中Apriori算法实现讲解
2017/12/10 Python
python微元法计算函数曲线长度的方法
2018/11/08 Python
python多进程读图提取特征存npy
2019/05/21 Python
python 模拟创建seafile 目录操作示例
2019/09/26 Python
python实现的读取网页并分词功能示例
2019/10/29 Python
Python : turtle色彩控制实例详解
2020/01/19 Python
python2.7使用scapy发送syn实例
2020/05/05 Python
Python读取Excel数据并生成图表过程解析
2020/06/18 Python
全球领先美式家具品牌:Ashley爱室丽家居
2017/08/07 全球购物
纽约复古灵感的现代珠宝品牌:Lulu Frost
2018/03/03 全球购物
Notino法国:购买香水和化妆品
2019/04/15 全球购物
网络安全方面的面试题
2016/01/07 面试题
劳动工资科岗位职责范本
2014/03/02 职场文书
三严三实对照检查材料
2014/09/22 职场文书
先进教师事迹材料
2014/12/16 职场文书
优秀党员个人总结
2015/02/14 职场文书
毕业证明书
2015/06/19 职场文书
2015年汽车销售员工作总结
2015/07/24 职场文书
Element-ui Layout布局(Row和Col组件)的实现
2021/12/06 Vue.js