ES6系列教程第四篇--asyn详解

2023-10-29

一、什么是async

    async其实是ES7的才有的关键字,放在这里说,其实是和我们前面所说的Promise,Generator有很大关联的。async的意思是"异步",顾名思义是有关异步操作有关的关键字。下面我们就来构造一个async方法。

async function helloAsync(){
    return "helloAsync";
  }
  console.log(helloAsync())//Promise {<resolved>: "helloAsync"}

   申明async方法比较简单,只需要在普通的函数前加上"async"关键字即可。我们执行下这个函数,发现并没有返回字符串"helloAsync",而是通过Promise.resolved()将字符串封装成了一个Promise对象返回。

   既然是返回的Promise对象,我们就是用then方法来处理。

async function helloAsync(){

  	return "helloAsync";

  }
  helloAsync().then(v=>{
     console.log(v);//"helloAsync"
  })

到这,道友们可能纳闷了,就是封装一个Promise的对象返回,这有个毛用啊。别急,await关键字闪亮登场。

二、await关键字

    在Generator章节中我们熟悉了yield关键字,yield关键字只能使用在Generator函数中,同样,await关键字也不能单独使用,是需要使用在async方法中。 await字面意思是"等待",那它是在等什么呢?它是在等待后面表达式的执行结果。

function testAwait(){
   return new Promise((resolve) => {
          setTimeout(function(){
          	console.log("testAwait");
          	resolve();
          }, 1000);
       });
  	}
  async function helloAsync(){
  	await testAwait();
  	console.log("helloAsync");
  }
  helloAsync();

我们来分析下这段代码

1、testAwait()方法中new一个Promise对象返回,promise对象中用setTimeout模拟一个异步过程,即1s后打印"testAwait"。

2、helloAsync()方法中,await testAwait(),表示将阻塞这里,等待testAwait这个异步方法执行并返回结果后,才继续下面的代码。

执行下,1s后打印了下面的日志。

到此,道友们是不是理解了await的作用,就是阻塞主函数的执行,直到后面的Promise函数返回结果。

聪明的道友可能要问,await后面只能 是Promise对象么?答案是否定的,可以是字符串,布尔值,数值以及普通函数。

function testAwait(){
  	setTimeout(function(){
          	console.log("testAwait");
          }, 1000);
  	}
  async function helloAsync(){
  	await testAwait();
  	console.log("helloAsync");
  }
  helloAsync();

执行结果:

方法没有报错,说明await后面是支持非Promise函数的,但是执行的结果是不一样的,所以await针对所跟的表达式不同,有两种处理方式:

1、对于Promise对象,await会阻塞主函数的执行,等待 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果,然后继续执行主函数接下来的代码。

2、对于非Promise对象,await等待函数或者直接量的返回,而不是等待其执行结果。

我们知道Promise对象有两种状态,除了resolved,还有rejected,我们来看下如果promise对象变为rejected,会如何处理。

function testAwait(){
  	return Promise.reject("error");
 }
  async function helloAsync(){
  	await testAwait();
  	console.log("helloAsync");//没有打印
  }
  helloAsync().then(v=>{
      console.log(v);
  }).catch(e=>{
     console.log(e);//"error"
  });

从执行结果看,返回reject状态被外层的catch捕获到,然后终止了后面的执行。

但是在有些情况下,出错后是希望继续执行,而不是中断。对于这种情况可以采用tcy...catch在函数内部捕获异常。

function testAwait(){
  		return Promise.reject("error");
  	}
  async function helloAsync(){
  	try{
       await testAwait();
  	}catch(e){
  		console.log("this error:"+e)//this error:error
  	} 	
  	console.log("helloAsync");//helloAsync
  }
  helloAsync().then(v=>{
  }).catch(e=>{
     console.log(e);//没有打印
  });

异常被try...catch捕获后,继续执行下面的代码,没有导致中断。

三、应用场景

   上面说到,await可以阻塞主函数,直到后面的Promise对象执行完成。这个特性就能很轻松的解决按顺序控制异步操作,即我们前一章节讲的异步流程的问题。

    道友们还记得在Generator章节的肚包鸡的制作过程的实例,我们用async/await来重写这个例子,并比较下两者实现的区别。

//准备
   function prepare(){
   	   return new Promise((resolve) => {
           setTimeout(function(){
             console.log("prepare chicken");
             resolve();
         },500)
       });  
   }

   //炒鸡
   function fired(){
        return new Promise((resolve) => {
           setTimeout(function(){
             console.log("fired chicken");
             resolve();
         },500)
       }); 
   }
   //炖鸡
   function stewed(){
        return new Promise((resolve) => {
           setTimeout(function(){
             console.log("stewed chicken");
             resolve();
         },500)
       }); 
   }
   //上料
   function sdd(){
        return new Promise((resolve) => {
           setTimeout(function(){
             console.log("sdd chicken");
             resolve();
         },500)
       }); 
   }
   //上菜
   function serve(){
        return new Promise((resolve) => {
           setTimeout(function(){
             console.log("serve chicken");
             resolve();
         },500)
       });
   }
   async function task(){
   	console.log("start task");
  	await prepare();
  	await fired();
  	await stewed();
  	await sdd();
  	await serve();
  	console.log("end task");
  }
  task();

这段代码看上去神清气爽,我们来分析下代码:

1、首先每个制作异步过程封装成Promise对象。

2、利用await阻塞原理,实现每个制作的顺序执行。

相比较Generator实现,无需run流程函数,完美的实现了异步流程。

四、总结

从Promise到Generator,再到async,对于异步编程的解决方案越来越完美,这就是ES6不断发展的魅力所在。

上一篇:ES6系列教程第三篇--Generator 详解                          下一篇:ES6系列教程第五篇--Class(一)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ES6系列教程第四篇--asyn详解 的相关文章

  • 如何确定并打印 jQuery 版本?

    是否有一个 jQuery 函数可以返回当前加载的 jQuery 版本 你可以使用这个 fn jquery or if you re using noConflict jQuery fn jquery 当 jQuery 构建时它会自动更新 定
  • JW Player javaScript API 不工作

    我使用 jwplayer version 5 10 2295 和浏览器 chrome 25 My code jwplayer container setup file path width 300px height 100px autost
  • 获取express.js中间件请求中“#”后的url

    我需要获取服务器中间件上的 url 使用express js 我用req url但是当 url 开头时 some urlreq url 返回 与req path 有没有办法获取url之后 在express js中 No URL 中以 符号永
  • 如何使用 HTML 5 实现类似 gmail 的文件上传/附件

    我记得一些支持 Ajax 之类的选项 无回发世界 文件上传 隐藏的 iframe 使用 flash 对象 尽管我仍然好奇为什么使用 SWF 以及它提供什么优势 然而 通过查看博客 HTML 5 似乎很有前途 我尝试了一些小示例 它确实有效
  • 使用 Firefox 插件 sdk 的 nsISocketTransportService

    我正在尝试使用 Firefox 来读取 SSH 横幅 IE 当您最初连接到 SSH 服务器时 服务器会向您发送其横幅 标识服务器软件 并且您向 SSH 服务器发送您的横幅 标识您的客户端软件 为此 我使用以下 URL 中的示例 firefo
  • 在随机位置启动 HTML5

    我有一个大约 2 小时长的音轨 我想在我的网站上使用它 我希望它在页面加载时在随机位置开始播放曲目 使用 HTML5 可以吗 我知道您可以使用 element currentTime 函数来获取当前位置 但是如何在完全下载之前获取曲目的总时
  • 设置双指缩放时精确的滚动位置

    我正在创建一个地图应用程序 它将标记图像放置在画布上并滚动到它 我正在使用浏览器的捏缩放和滚动来放大 缩小地图 然而 我注意到有一些奇怪的行为 我想知道如何解决它 这有点难以解释 但我们开始吧 假设您处于网页的标准缩放级别 无法进一步缩小
  • 在javascript中访问函数内的实例变量?

    如何以最简单的方式访问函数内的实例变量 function MyObject Instance variables this handler Methods this enableHandler function var button doc
  • jQuery输入文件点击方法和IE上拒绝访问

    我尝试仅使用一个按钮作为输入文件 它在 Firefox Chrome Safari 中工作正常 但在 IE 中不行 提交表单时我总是收到 访问被拒绝 的消息 代码 input file click 有真正的解决方法吗 我在谷歌上浪费了大约2
  • API 使用令牌向 odoo 进行身份验证

    我想使用令牌从 Express 应用程序向 Odoo 进行身份验证 我在用odoo xmlrpc https www npmjs com package odoo xmlrpc连接 Odoo 的节点模块 我的快递应用程序 Odoo 要求 A
  • 访问 nuxt 配置文件中的存储

    我想添加通过 Nuxt 静态生成的动态路由 我定义了一个客户端 服务器端存储asyncData方法 我想将这个存储值 一个数组 映射到我的nuxt config js文件使其成为 动态 静态 路线图nuxt generate命令 但如何访问
  • React JS 服务器端问题 - 找不到窗口

    你好 我正在尝试在我的reactJS项目中使用react rte 我有服务器端渲染 每次我想使用这个包时 我都会得到 return msie 6 9 b test window navigator userAgent toLowerCase
  • 为什么这行带有“await”的代码会触发微任务队列处理?

    以下引用是我理解微任务队列处理的主要参考 当 JS 堆栈清空时 就会处理微任务 承诺使用 杰克 阿奇博尔德 https twitter com jaffathecake status 954653170986311680 这对我来说没有意义
  • JavaScript中如何确保输入的值是数字而不是字符串?

    我创建了这个函数 function num var x prompt please enter your first number var y prompt please enter your second number if isNaN
  • 如何将 arraylist 从 servlet 传递到 javascript?

    我通过在属性中设置数组列表并将其转发到 jsp 来从 servlet 传递数组列表 Servlet ArrayList
  • 模板中带有 ng-if 的 angularjs 指令

    我正在构建一个在模板内使用 ng if 的指令 奇怪的是 提供给链接函数的元素没有扩展ng if代码 它只是ng if的注释行 经过一番尝试 我发现通过将链接代码包装在 timeout 中似乎可以使其正常工作 但我想知道这是否不是正确的处理
  • ThreeJS 中阴影的奇怪行为

    所以我有一个 ThreeJS 场景 并且添加了一些球体 多材质 我还添加了定向光 this light new THREE DirectionalLight 0xFFFFFF 1 this light position set 2 10 2
  • 在 JavaScript 函数的 Django 模板中转义字符串参数

    我有一个 JavaScript 函数 它返回一组对象 return Func id name 例如 我在传递包含引号的字符串时遇到问题 Dr Seuss ABC BOOk 是无效语法 I tried name safe 但无济于事 有什么解
  • d3.event.translate 在触摸设备的缩放上包含 NaN

    我使用 d3 为我的 svg 编写了一个自定义缩放函数 如下所示 Zoom behavior function myzoom xpos d3 event translate 0 ypos d3 event translate 1 vis a
  • ng-include 和 ng-view 不同时加载

    下面是我的应用程序的结构 很简单 页眉和页脚是非常小的文件 而主页上的 ng view 要大得多 当我进入该页面时 我注意到了这一点 首先加载两个 ng include 然后 ng view 出现 页脚被推到底部 页脚闪烁大约 0 1 秒

随机推荐

  • C++ inline内联函数详解

    函数是一个可以重复使用的代码块 CPU 会一条一条地挨着执行其中的代码 CPU 在执行主调函数代码时如果遇到了被调函数 主调函数就会暂停 CPU 转而执行被调函数的代码 被调函数执行完毕后再返回到主调函数 主调函数根据刚才的状态继续往下执行
  • for循环2(python)

    在python中 for循环的功能更加强大 对于可迭代对象的遍历更加的方便 可迭代对象 字符串 列表 元组等可以通过下标来访问元素的数据类型 同时这种数据类型也可以使用切片 例如我们遍历一个字符串 str hello for i in st
  • python时间序列动图_Python绘制时间序列数据的时序图、自相关图和偏自相关图

    时序图 自相关图和偏相关图是判断时间序列数据是否平稳的重要依据 本文涉及的扩展库numpy pandas statsmodels一般可以使用pip进行在线安装 如果安装失败 可以到http www lfd uci edu gohlke py
  • Java 基本命名规则

    一 项目名称 所有单词全部用小写 如 testjavaproject studentmanagement等 二 Java project中相关命名 1 包名 包名统一使用小写 点分隔符之间有且仅有一个自然语义的英语单词 用域名反过来写 不会
  • 关于uni-app课程开发的一心一得

    在当今互联网和移动互联网的时代 APP成为了人们生活和工作中不可或缺的一部分 而对于开发者来说 如何快速 高效 跨平台地开发一款APP也成为了关注焦点 而Uni App就是一种可以快速开发跨平台APP的方式 通过一套代码可以同时发布到多个平
  • Python3《机器学习实战》学习笔记(四):朴素贝叶斯实战篇之新浪新闻分类

    一 朴素贝叶斯改进之拉普拉斯平滑 上篇文章提到过 算法存在一定的问题 需要进行改进 那么需要改进的地方在哪里呢 利用贝叶斯分类器对文档进行分类时 要计算多个概率的乘积以获得文档属于某个类别的概率 即计算p w0 1 p w1 1 p w2
  • cocos2d-html5 碰撞检测的几种方法

    游戏中的碰撞还是比较多的 比如角色与角色的碰撞 角色与墙壁的碰撞 角色与怪物的碰撞等 都需要 进行碰撞的检测 来触发一定的事件 最近在尝试制作一个小游戏的时候需要用到碰撞检测 然后就查了下资料 并在论坛进行提问等算是找到了比较满意的碰撞检测
  • 大白话用Transformer做Object Detection

    作者 张恒 单位 法国国家信息与自动化研究所 研究方向 目标检测 传感器融合 记录一下隔离期间学习的 DETR 1 系列文章 追求简单 清晰 易懂 分上下两部分 上篇介绍 DETR 的基本原理 下篇是针对 DETR 缺点的改进工作 大白话
  • Android动态权限申请框架

    XmPermissions 项目介绍 Android动态权限申请框架 Github地址 https github com lhm0603 XmPermissionsProject 使用说明 XmPermissions 支持 Android
  • 2020年蓝桥杯

    专栏 蓝桥杯题目 目录 一 门牌制作 二 跑步锻炼 三 蛇形填数 四 排序 五 寻找2020 六 成绩统计 七 单词分析 八 数字三角形 九 平面切分 一 门牌制作 题目描述 小蓝要为一条街的住户制作门牌号 这条街一共有2020 位住户 门
  • 【NLP】第 1 章 : 语言模型简介

    使人不同于地球上其他动物物种的最大发展之一是语言的进化 这使我们能够交流和交流想法和思想 从而导致包括互联网在内的许多科学发现 这就是语言的重要性 因此 当我们涉足人工智能领域 时 除非我们确保机器能够理解和理解自然语言 否则在那里取得的进
  • 【linux】Grok Debugger本地安装过程

    1 概述 转载 https blog 51cto com fengwan 1758845 最近在使用ELK对日志进行集中管理 因为涉及到日志的规则经常要用到http grokdebug herokuapp com 进行调试 但是因为国内网络
  • nacos配置中心将原来的配置读取到配置中心并且应用

    将模块的所有配置放到配置中心里去 刚才说了那么多 我们可以将数值储存在配置中心 及时调用 那么我们是否可以将我们之前的配置放到配置中心里呢 let s go 我们当前的配值如下 spring datasource username root
  • thymeleaf固定前端信息的循环次数

    thymeleaf固定前端信息的循环次数 div class part body div
  • ajax 禁止跨域,AJAX_解决AJAX中跨域访问出现''没有权限''的错误,禁止访问非同域的网站,下面一 - phpStudy...

    解决AJAX中跨域访问出现 没有权限 的错误 禁止访问非同域的网站 下面一个例子来访问http www google cn function createobj if window ActiveXObject return new Acti
  • 鱼类识别系统:基于深度学习的生态保护与渔业管理利器【鱼类识别

    请接收一份来自大厂的保姆级面试稿 如何优雅的介绍自己的项目经验 诺瓦一面后测评 合肥就业求职好公司及薪资汇总 基恩士全流程 已测评等消息中 有无学历厂推荐 2023基恩士面经 送上一首凉凉 虹软24届校招提前批 笔试本周日开始 算法类看这里
  • Nginx的upstream_response_time

    转载请注明文章出处 tlanyan me upstream re 前几日为了查看FPM的性能 在Nginx的配置里增加FPM响应时间的header http server location php add header X Upstream
  • python3 dataframe中列数据为字典,拆分成多列或转存某个关键字的值

    下载到的数据里常有某列中为字典格式的数据 想把字典中的数据独立成列方便读取 或者读取字典中某个关键字的值独立存放 例如 A列中字典关键字type1的值存放到B列 解决思路 1 将A列格式转换为列表 2 列表再转换为dataframe 3 直
  • Linux 代理服务器 squid 安装和使用 [正向代理]

    目录 什么是 squid 相关版本 代理服务器相关配置 squid 安装 启动 squid 服务 修改配置文件 设置需要代理的 ip 查看服务运行状态 客户端的使用 软件自带代理功能 mac 网络偏好设置 全局代理 指定应用程序走代理 什么
  • ES6系列教程第四篇--asyn详解

    一 什么是async async其实是ES7的才有的关键字 放在这里说 其实是和我们前面所说的Promise Generator有很大关联的 async的意思是 异步 顾名思义是有关异步操作有关的关键字 下面我们就来构造一个async方法