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 相关文章推荐
csdn 论坛技术区平均给分功能
Nov 07 Javascript
javascript中encodeURI和decodeURI方法使用介绍
May 06 Javascript
JS实现拖动示例代码
Nov 01 Javascript
jQuery 顶部导航跟随滚动条滚动固定浮动在顶部
Jun 06 Javascript
jQuery+PHP+MySQL实现无限级联下拉框效果
Feb 19 Javascript
js点击返回跳转到指定页面实现过程
Aug 20 Javascript
bootstrap中添加额外的图标实例代码
Feb 15 Javascript
JS实现电商放大镜效果
Aug 24 Javascript
Angular异步变同步处理方法
Aug 13 Javascript
vue中created和mounted的区别浅析
Aug 13 Javascript
JS异步处理的进化史深入讲解
Aug 25 Javascript
jquery css实现流程进度条
Mar 26 jQuery
详解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
DW中链接mysql数据库时,建立字符集中文出现乱码的解决方法
2010/03/27 PHP
详细解读php的命名空间(一)
2018/02/21 PHP
PHP+Oracle本地开发环境搭建方法详解
2019/04/01 PHP
安装docker和docker-compose实例详解
2019/07/30 PHP
Javascript remove 自定义数组删除方法
2009/10/20 Javascript
js判断输入是否为数字的具体实例
2013/08/03 Javascript
解决JS中乘法的浮点错误的方法
2014/01/03 Javascript
js读取json的两种常用方法示例介绍
2014/10/19 Javascript
node.js开机自启动脚本文件
2014/12/24 Javascript
angularJS 中$attrs方法使用指南
2015/02/09 Javascript
深入理解JavaScript系列(29):设计模式之装饰者模式详解
2015/03/03 Javascript
node.js 动态执行脚本
2016/06/02 Javascript
微信小程序通过api接口将json数据展现到小程序示例
2017/01/20 Javascript
基于JavaScript实现焦点图轮播效果
2017/03/27 Javascript
Vue学习笔记进阶篇之过渡状态详解
2017/07/14 Javascript
JavaScript函数绑定用法实例分析
2017/11/14 Javascript
Vuex提升学习篇
2018/01/11 Javascript
浅谈KOA2 Restful方式路由初探
2019/03/14 Javascript
javascript实现blob加密视频源地址的方法
2019/08/08 Javascript
Vue 使用beforeEach实现登录状态检查功能
2019/10/31 Javascript
原生JS实现烟花效果
2020/03/10 Javascript
[05:15]DOTA2英雄梦之声_第16期_灰烬之灵
2014/06/21 DOTA
分析Python编程时利用wxPython来支持多线程的方法
2015/04/07 Python
Python模拟登陆淘宝并统计淘宝消费情况的代码实例分享
2016/07/04 Python
详解Python多线程
2016/11/14 Python
python中 logging的使用详解
2017/10/25 Python
django 实现后台从富文本提取纯文本
2020/07/02 Python
PyCharm2019 安装和配置教程详解附激活码
2020/07/31 Python
英国最大的在线奢侈手表零售商:Jura Watches
2018/01/29 全球购物
莫斯科大型旅游休闲商品超市:Camping.ru
2020/09/16 全球购物
中专自我鉴定范文
2013/10/16 职场文书
高级销售求职信
2014/02/21 职场文书
社会工作专业自荐信
2014/09/26 职场文书
抗洪救灾感谢信
2015/01/22 职场文书
防汛通知
2015/04/25 职场文书
navicat 连接Ubuntu虚拟机的mysql的操作方法
2022/04/02 MySQL