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对象是否可用的最正确方法分析
Oct 03 Javascript
5秒后跳转效果(setInterval/SetTimeOut)
May 03 Javascript
js中通过父级进行查找定位元素
Jun 15 Javascript
JavaScript让网页出现渐隐渐显背景颜色的方法
Apr 21 Javascript
在JavaScript中处理时间之setMinutes()方法的使用
Jun 11 Javascript
jQuery简单实现title提示效果示例
Aug 01 Javascript
canvas实现粒子时钟效果
Feb 06 Javascript
基于js中this和event 的区别(详解)
Oct 24 Javascript
vue内置组件transition简单原理图文详解(小结)
Jul 12 Javascript
JS实现点击li标签弹出对应的索引功能【案例】
Feb 18 Javascript
微信小程序实现日期格式化和倒计时
Nov 01 Javascript
JavaScript实现网页留言板功能
Nov 23 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函数,php爱好者站推荐
2007/03/19 PHP
PHP程序级守护进程的实现与优化的使用概述
2013/05/02 PHP
如何在Ubuntu下启动Apache的Rewrite功能
2013/07/05 PHP
php的curl封装类用法实例
2014/11/07 PHP
帝国cms目录结构分享
2015/07/06 PHP
PHP 7.0.2 正式版发布
2016/01/08 PHP
PHP实现笛卡尔积算法的实例讲解
2019/12/22 PHP
JavaScript QueryString解析类代码
2010/01/17 Javascript
jquery自动切换tabs选项卡的具体实现
2013/12/24 Javascript
JS延迟加载加快页面打开速度示例代码
2013/12/30 Javascript
兼容最新firefox、chrome和IE的javascript图片预览实现代码
2014/08/08 Javascript
jQuery的animate函数学习记录
2014/08/08 Javascript
JS上传图片前实现图片预览效果的方法
2015/03/02 Javascript
js获取表格的行数和列数的方法
2015/10/23 Javascript
javascript动态获取登录时间和在线时长
2016/02/25 Javascript
原生js编写基于面向对象的分页组件
2016/12/05 Javascript
vue 挂载路由到头部导航的方法
2017/11/13 Javascript
nodeJs爬虫的技术点总结
2018/05/13 NodeJs
jQuery实现上下滚动公告栏详细代码
2018/11/21 jQuery
layui实现form表单同时提交数据和文件的代码
2019/10/25 Javascript
js仿360开机效果
2019/12/26 Javascript
借助云开发实现小程序短信验证码的发送
2020/01/06 Javascript
react国际化化插件react-i18n-auto使用详解
2020/03/31 Javascript
JavaScript中clientWidth,offsetWidth,scrollWidth的区别
2021/01/25 Javascript
[02:16]DOTA2英雄基础教程 干扰者
2014/01/15 DOTA
[40:27]完美世界DOTA2联赛PWL S3 PXG vs GXR 第一场 12.19
2020/12/24 DOTA
Python使用arrow库优雅地处理时间数据详解
2017/10/10 Python
python 限制函数调用次数的实例讲解
2018/04/21 Python
python交易记录链的实现过程详解
2019/07/03 Python
Pycharm简单使用教程(入门小结)
2019/07/04 Python
简单了解python的内存管理机制
2019/07/08 Python
怎么写自荐书范文
2014/02/12 职场文书
打造高效课堂实施方案
2014/03/22 职场文书
社团活动总结模板
2014/06/30 职场文书
殡葬服务心得体会
2014/09/11 职场文书
不会写演讲稿,快来看看这篇文章!
2019/08/06 职场文书