ES7:异步神器async-await(我看过讲得最清晰透彻的文章)

2024-04-02 15:58

本文主要是介绍ES7:异步神器async-await(我看过讲得最清晰透彻的文章),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景:

关于异步处理,ES5的回调使我们陷入地狱,ES6Promise使我们脱离魔障,终于、ES7async-await带我们走向光明。今天就来学习一下 async-await

async-await和Promise的关系

经常会看到有了 async-await、promise 还有必要学习吗、async await优于promise的几个特点,接收了这些信息后,就蒙圈了。现在才知道,async-awaitpromise和generator的语法糖。只是为了让我们书写代码时更加流畅,当然也增强了代码的可读性。简单来说:async-await 是建立在 promise机制之上的,并不能取代其地位。

基本语法

async function basicDemo() {let result = await Math.random();console.log(result);
}basicDemo();
// 0.6484863241051226
//Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: undefined}

上述代码就是async-await的基本使用形式。有两个陌生的关键字async、await,同时函数执行结果似乎返回了一个promise对象。

await

await 可以理解为是 async wait 的简写。await 必须出现在 async 函数内部,不能单独使用。

function notAsyncFunc() {await Math.random();
}
notAsyncFunc();//Uncaught SyntaxError: Unexpected identifier

await 后面可以跟任何的JS 表达式。虽然说 await 可以等很多类型的东西,但是它最主要的意图是用来等待 Promise 对象的状态被 resolved。如果await的是 promise对象会造成异步函数停止执行并且等待 promise 的解决,如果等的是正常的表达式则立即执行。

function sleep(second) {return new Promise((resolve, reject) => {setTimeout(() => {resolve(' enough sleep~');}, second);})
}
function normalFunc() {console.log('normalFunc');
}
async function awaitDemo() {await normalFunc();console.log('something, ~~');let result = await sleep(2000);console.log(result);// 两秒之后会被打印出来
}
awaitDemo();
// normalFunc
// VM4036:13 something, ~~
// VM4036:15  enough sleep~

希望通过上面的 demo,大家可以理解我上面的话。

实例

举例说明啊,你有三个请求需要发生,第三个请求是依赖于第二个请求的解构第二个请求依赖于第一个请求的结果。若用 ES5实现会有3层的回调,若用Promise 实现至少需要3个then。一个是代码横向发展,另一个是纵向发展。今天指给出 async-await 的实现哈~

//我们仍然使用 setTimeout 来模拟异步请求
function sleep(second, param) {return new Promise((resolve, reject) => {setTimeout(() => {resolve(param);}, second);})
}async function test() {let result1 = await sleep(2000, 'req01');let result2 = await sleep(1000, 'req02' + result1);let result3 = await sleep(500, 'req03' + result2);console.log(`${result3}${result2}${result1}`);
}test();
//req03req02req01
//req02req01
//req01

错误处理

上述的代码好像给的都是resolve的情况,那么reject的时候我们该如何处理呢?

function sleep(second) {return new Promise((resolve, reject) => {setTimeout(() => {reject('want to sleep~');}, second);})
}async function errorDemo() {let result = await sleep(1000);console.log(result);
}
errorDemo();// VM706:11 Uncaught (in promise) want to sleep~// 为了处理Promise.reject 的情况我们应该将代码块用 try catch 包裹一下
async function errorDemoSuper() {try {let result = await sleep(1000);console.log(result);} catch (err) {console.log(err);}
}errorDemoSuper();// want to sleep~
// 有了 try catch 之后我们就能够拿到 Promise.reject 回来的数据了。

小心你的并行处理!!!

我这里为啥加了三个感叹号呢~,因为对于初学者来说一不小心就将 ajax 的并发请求发成了阻塞式同步的操作了,我就真真切切的在工作中写了这样的代码。await 若等待的是 promise 就会停止下来。业务是这样的,我有三个异步请求需要发送,相互没有关联,只是需要当请求都结束后将界面的 loading 清除掉即可。
刚学完 async await 开心啊,到处乱用~

function sleep(second) {return new Promise((resolve, reject) => {setTimeout(() => {resolve('request done! ' + Math.random());}, second);})
}async function bugDemo() {await sleep(1000);await sleep(1000);await sleep(1000);console.log('clear the loading~');
}bugDemo();

loading 确实是等待请求都结束完才清除的。但是你认真的观察下浏览器的 timeline 请求是一个结束后再发另一个的(若观察效果请发真实的 ajax 请求)
那么,正常的处理是怎样的呢?

async function correctDemo() {let p1 = sleep(1000);let p2 = sleep(1000);let p3 = sleep(1000);await Promise.all([p1, p2, p3]);console.log('clear the loading~');
}
correctDemo();// clear the loading~

恩, 完美。看吧~ async-await并不能取代promise.

await in for 循环

最后一点了,await必须在async函数的上下文中的。

// 正常 for 循环
async function forDemo() {let arr = [1, 2, 3, 4, 5];for (let i = 0; i < arr.length; i ++) {await arr[i];}
}
forDemo();//正常输出
// 因为想要炫技把 for循环写成下面这样
async function forBugDemo() {let arr = [1, 2, 3, 4, 5];arr.forEach(item => {await item;});
}
forBugDemo();// Uncaught SyntaxError: Unexpected identifier

for内使用await不会报错(因为for不是函数),在forEach里报错了,意为即使在async函数内包其它函数,也不能在该函数内使用await,可以理解为演示作用域。

综上,希望大家看了能得到帮助和提升!请带着原因指正和批评,多谢

这篇关于ES7:异步神器async-await(我看过讲得最清晰透彻的文章)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/870415

相关文章

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

js异步提交form表单的解决方案

1.定义异步提交表单的方法 (通用方法) /*** 异步提交form表单* @param options {form:form表单元素,success:执行成功后处理函数}* <span style="color:#ff0000;"><strong>@注意 后台接收参数要解码否则中文会导致乱码 如:URLDecoder.decode(param,"UTF-8")</strong></span>

java计算机毕设课设—停车管理信息系统(附源码、文章、相关截图、部署视频)

这是什么系统? 资源获取方式在最下方 java计算机毕设课设—停车管理信息系统(附源码、文章、相关截图、部署视频) 停车管理信息系统是为了提升停车场的运营效率和管理水平而设计的综合性平台。系统涵盖用户信息管理、车位管理、收费管理、违规车辆处理等多个功能模块,旨在实现对停车场资源的高效配置和实时监控。此外,系统还提供了资讯管理和统计查询功能,帮助管理者及时发布信息并进行数据分析,为停车场的科学

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑燃料电池和电解槽虚拟惯量支撑的电力系统优化调度方法》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源程序擅长文章解读,论文与完整源程序,等方面的知识,电网论文源程序关注python

AsyncTask 异步任务解析

1:构建AsyncTask 子类的回调方法: A:doInBackground:   必须重写,所有的耗时操作都在这个里面进行; B: onPreExecute:     用户操作数据前的调用; 例如:显示一个进度条 等 ; C: onPostExecute:    当doInBackground 执行完成后;会自动把数据传给onPostExecute方法;也就是说:这个方法是处理返回的数据的方法

以后写代码都是AI自动写了,Cursor+Claude-3.5-Sonnet,Karpathy 点赞的 AI 代码神器。如何使用详细教程

Cursor 情况简介 AI 大神 Andrej Karpathy 都被震惊了!他最近在试用 VS Code Cursor +Claude Sonnet 3.5,结果发现这玩意儿比 GitHub Copilot 还好用! Cursor 在短短时间内迅速成为程序员群体的顶流神器,其背后的原因在于其默认使用 OpenAI 投资的 Claude-3.5-Sonnet 模型,这一举动不仅改变了代码生成

OBItools:Linux下的DNA条形码分析神器

在生物信息学领域,DNA条形码分析是一种非常常见的研究方法,用于物种鉴定、生态学和进化生物学研究。今天要介绍的工具就是专为此设计的——OBItools。这个工具集专门用于处理生态学和进化生物学中的DNA条形码数据,在Linux环境下运行。无论你是本科生还是刚入门的科研人员,OBItools都能为你提供可靠的帮助。 OBItools的功能亮点 OBItools是一个强大的工具包,特别适合DNA条形

使用Node-API进行异步任务开发

一、Node-API异步任务机制概述         Node-API异步任务开发主要用于执行耗时操作的场景中使用,以避免阻塞主线程,确保应用程序的性能和响应效率。         1、应用场景: 文件操作:读取大型文件或执行复杂的文件操作时,可以使用异步工作项来避免阻塞主线程。网络请求:当需要进行网络请求并等待响应时,可以使用异步工作项来避免阻塞主线程,从而提高应用程序的响应性能。数据库操

【Linux】萌新看过来!一篇文章带你走进Linux世界

🚀个人主页:奋斗的小羊 🚀所属专栏:Linux 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 前言💥1、初识Linux💥1.1 什么是操作系统?💥1.2 各种操作系统对比💥1.3 现代Linux应用💥1.4 Linux常用版本 💥2、Linux 和 Windows 目录结构对比💥2.1 文件系统组织方式💥2.2