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 相关文章推荐
Javascript - HTML的request类
Jan 09 Javascript
jQuery使用手册之 事件处理
Mar 24 Javascript
jQuery 动态酷效果实现总结
Dec 27 Javascript
jquery中dom操作和事件的实例学习 下拉框应用
Dec 01 Javascript
js 实现在离开页面时提醒未保存的信息(减少用户重复操作)
Jan 16 Javascript
JQuery+DIV自定义滚动条样式的具体实现
Jun 25 Javascript
JS中数组重排序方法
Nov 11 Javascript
javascript 实现文本使用省略号替代(超出固定高度的情况)
Feb 21 Javascript
jQuery插件HighCharts实现的2D面积图效果示例【附demo源码下载】
Mar 15 Javascript
vue快捷键与基础指令详解
Jun 01 Javascript
Angular 4依赖注入学习教程之Injectable装饰器(六)
Jun 04 Javascript
vue中使用百度脑图kityminder-core二次开发的实现
Sep 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获取网络文件的实现代码
2010/01/01 PHP
CI(CodeIgniter)框架中的增删改查操作
2014/06/10 PHP
php实现Linux服务器木马排查及加固功能
2014/12/29 PHP
Laravel 队列使用的实现
2019/01/08 PHP
基于PHP+mysql实现新闻发布系统的开发
2020/08/06 PHP
js将控件隐藏的方法及display属性介绍
2013/07/04 Javascript
JavaScript运行时库属性一览表
2014/03/14 Javascript
Javascript实现简单二级下拉菜单实例
2014/06/15 Javascript
js实现checkbox全选、不选与反选的方法
2015/02/09 Javascript
Vue中建立全局引用或者全局命令的方法
2017/08/21 Javascript
微信小程序实现动态设置placeholder提示文字及按钮选中/取消状态的方法
2017/12/14 Javascript
微信小程序使用component自定义toast弹窗效果
2018/11/27 Javascript
element中table高度自适应的实现
2020/10/21 Javascript
[02:16]完美世界DOTA2联赛PWL S3 集锦第三期
2020/12/21 DOTA
用实例说明python的*args和**kwargs用法
2013/11/01 Python
使用 Python 获取 Linux 系统信息的代码
2014/07/13 Python
Python中下划线的使用方法
2015/03/27 Python
Python实现生成随机数据插入mysql数据库的方法
2017/12/25 Python
pandas 实现字典转换成DataFrame的方法
2018/07/04 Python
对pandas的算术运算和数据对齐实例详解
2018/12/22 Python
pycharm 批量修改变量名称的方法
2019/08/01 Python
python主线程与子线程的结束顺序实例解析
2019/12/17 Python
python实现简单井字棋游戏
2020/03/04 Python
快速解决Django关闭Debug模式无法加载media图片与static静态文件
2020/04/07 Python
浅谈matplotlib中FigureCanvasXAgg的用法
2020/06/16 Python
Python3.9.1中使用match方法详解
2021/02/08 Python
实习自我鉴定模板
2013/09/28 职场文书
银行职员思想汇报
2013/12/31 职场文书
店长职务说明书
2014/02/04 职场文书
高中军训感言200字
2014/02/23 职场文书
农林环境专业求职信
2014/03/13 职场文书
中班上学期幼儿评语
2014/04/30 职场文书
竞聘演讲稿开场白
2014/08/25 职场文书
2014银行领导班子群众路线对照检查材料思想汇报
2014/09/17 职场文书
预备党员群众路线教育实践活动思想汇报2014
2014/10/25 职场文书
2014教师年度工作总结
2014/11/10 职场文书