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 相关文章推荐
在线编辑器的实现原理(兼容IE和FireFox)
Mar 09 Javascript
屏蔽F1~F12的快捷键的js函数
May 06 Javascript
JS实现在Repeater控件中创建可隐藏区域的代码
Sep 16 Javascript
JavaScript使用IEEE 标准进行二进制浮点运算产生莫名错误的解决方法
May 28 Javascript
jQuery调取jSon数据并展示的方法
Jan 29 Javascript
AngularJS directive返回对象属性详解
Mar 28 Javascript
js HTML5多图片上传及预览实例解析(不含前端的文件分割)
Aug 26 Javascript
利用js来实现缩略语列表、文献来源链接和快捷键列表
Dec 16 Javascript
jQuery选择器之子元素选择器详解
Sep 18 jQuery
微信小程序 确认框的实现(附代码)
Jul 23 Javascript
使用vue制作滑动标签
Sep 21 Javascript
laravel实现中文和英语互相切换的例子
Sep 30 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
163的邮件用phpmailer发送(实例详解)
2013/06/24 PHP
thinkPHP导出csv文件及用表格输出excel的方法
2015/12/30 PHP
Yii2中YiiBase自动加载类、引用文件方法分析(autoload)
2016/07/25 PHP
PHP实现的只保留字符串首尾字符功能示例【隐藏部分字符串】
2019/03/11 PHP
javascript 客户端验证上传图片的大小(兼容IE和火狐)
2009/08/15 Javascript
ExtJS Ext.MessageBox.alert()弹出对话框详解
2010/04/02 Javascript
js调用activeX获取u盘序列号的代码
2011/11/21 Javascript
jQuery文字横向滚动效果的实现代码
2016/05/31 Javascript
javascript基础语法——全面理解变量和标识符
2016/06/02 Javascript
Javascript typeof与instanceof的区别
2016/10/18 Javascript
webpack 2.x配置reactjs基本开发环境详解
2017/08/08 Javascript
AngularJS实现表单元素值绑定操作示例
2017/10/11 Javascript
使用use注册Vue全局组件和全局指令的方法
2018/03/08 Javascript
搭建vue开发环境
2018/07/19 Javascript
js console.log打印对象时属性缺失的解决方法
2019/05/23 Javascript
深入理解redux之compose的具体应用
2020/01/12 Javascript
Python多线程编程(二):启动线程的两种方法
2015/04/05 Python
python3+PyQt5实现自定义窗口部件Counters
2018/04/20 Python
Python常见数字运算操作实例小结
2019/03/22 Python
Python pandas.DataFrame调整列顺序及修改index名的方法
2019/06/21 Python
python绘制封闭多边形教程
2020/02/18 Python
Python自动登录QQ的实现示例
2020/08/28 Python
Vs Code中8个好用的python 扩展插件
2020/10/12 Python
CSS3 创建网页动画实现弹跳球动效果
2018/10/30 HTML / CSS
html5 乒乓球(碰撞检测)实例二
2013/07/25 HTML / CSS
使用html2canvas实现将html内容写入到canvas中生成图片
2020/01/03 HTML / CSS
基于html5 canvas做批改作业的小插件
2020/05/20 HTML / CSS
BCBG官网:BCBGMAXAZRIA
2017/12/29 全球购物
万宝龙英国官网:Montblanc手表、书写工具、皮革和珠宝
2018/10/16 全球购物
本科生学习总结的自我评价
2013/10/02 职场文书
平面设计自荐信
2013/10/07 职场文书
文员岗位职责
2013/11/09 职场文书
保护动物倡议书
2014/04/15 职场文书
2015年医院药剂科工作总结
2015/05/04 职场文书
刑事附带民事起诉状
2015/05/19 职场文书
JavaScript流程控制(循环)
2021/12/06 Javascript