async 与 await(JavaScript)

目录捏

  • 前言
  • 一、async
  • 二、await
  • 三、使用方法
  • 总结


前言

在这里插入图片描述

async / awaitES2017(ES8) 提出的基于 Promise 解决异步的最终方案。上一篇文章介绍了 回调地狱 与 Promise(JavaScript),因为 Promise 的编程模型依然充斥着大量的 then 方法,其虽然解决了回调地狱的问题,但是在语义化及代码可读性方面依然存在缺陷,这就是 async / await 出现的原因。


一、async

  • async(异步):用来声明一个异步函数;await(async wait):用来等待异步函数执行
  • async 是一个加在函数前的修饰符,被 async 定义的函数会默认返回一个 Promise 对象 resolve 的值,因此对 async 函数可以直接使用 then 方法
   // 默认返回 Promise 对象成功值
   async function fun() {
       console.log('用户数据读取中~~');
       return '用户数据读取成功!!';
   }
   fun().then(val => {
       console.log(val)
   })

在这里插入图片描述

	// 根据 Promise 对象决定返回值
	async function fun() {
	    console.log('用户数据读取中~~')
	    return new Promise((resolve, reject) => {
	        setTimeout(() => {
	            resolve('用户数据读取成功!!')
	        }, 3000)
	    })
	}
	
	fun().then(value => {
	    console.log(value)
	})
	
	console.log(1);
	console.log(2);
	console.log(3);

在这里插入图片描述

二、await

若单有 async,则和 Promise 功能相似,但配合上 await 则效果完全不同

  • await 也是一个修饰符,只能放在 async 定义的函数内
  • await 修饰的若是 Promise 对象:可获取 Promise 中返回的内容( resolvereject 的参数),并会阻塞该函数内后面的代码直到获取到返回值后语句才会往下执行;若不是 Promise 对象:将此非 Promise 的语句当做 await 表达式的结果
	 // 非 Promise 对象
	 async function fun() {
	     console.log('用户数据读取中~~');
	     let a = await '用户数据读取成功!!';
	     console.log(a);
	 }
	 fun()

在这里插入图片描述

	async function fun() {
	    console.log('用户数据读取中~~')
	    console.log(1);
	    console.log(2);
	    console.log(3);
	    // Promise 对象
	    let a = await new Promise((resolve, reject) => {
	        setTimeout(() => {
	            resolve('用户数据读取成功!!')
	        }, 3000)
	    })
	    console.log(a);
	}
	
	fun()

在这里插入图片描述

	async function fun() {
	    let a = await 768
	    console.log(a)
	    let b = await '用户数据读取中...'
	    console.log(b)
	    // 注意:此处等待对象为函数,故需通过()调用
	    let c = await function () {
	        return '预计时间:3s'
	    }()
	    console.log(c)
	    let d = await new Promise((resolve, reject) => {
	        setTimeout(function () {
	            resolve('用户数据读取成功!!')
	        }, 3000)
	    })
	    console.log(d)
	}
	
	fun()

在这里插入图片描述

由以上案例可知 await 不仅可以用于等 Promise 对象,还可以等任意表达式,即 await 后面实际是可以接普通函数调用或者直接量的。不过我们更多的是放一个返回 Promise 对象的表达式,它等待的是 Promise 对象执行完毕所返回的结果。

	 // 非 Promise 对象
	function notPromise(time) {
	    setTimeout(() => {
	        console.log(time);
	        return 1;
	    }, time)
	}
	
	async function fun() {
		// 将 notPromise 所执行语句当做 await 表达式的结果
	    let a = await notPromise(3000);
	    let b = notPromise(2000);
	    let c = await notPromise(1000);
	    console.log(a);
	    console.log('先执行我捏~')
	}
	
	fun();

在这里插入图片描述

三、使用方法

	// 定义一个异步函数,time秒后才能获取到值
	function fun(time) {
		// Promise 对象
	    return new Promise((resolve, reject) => {
	        setTimeout(() => {
	            resolve('用户数据读取成功!!')
	        }, time)
	    })
	}
	
	async function test() {
	    console.log(1);
	    console.log(2);
	    console.log(3);
	    // 获取到 Promise 对象所返回的结果( resolve参数 )
	    let a = await fun(3000);
	    console.log(a)
	}
	
	test()

在这里插入图片描述

上一篇文章 回调地狱 与 Promise(JavaScript)中通过 Promise 解决了回调地狱问题,但不断地调用 then 链使代码看起来十分冗余从而导致可读性变差,故本文通过 asysc 与 await 来简化上文代码。

问题回顾:分别间隔 3s、2s、1s 按顺序输出:我在定时器1里捏!!我在定时器2里捏!!我在定时器3里捏!!

在这里插入图片描述

await 的优势在于简化处理 then 链,使 异步代码 的书写方式更接近于 同步代码

	function promise(value, time) {
	    return new Promise((resolve, reject) => {
	        setTimeout(() => {
	            resolve(value)
	        }, time)
	    })
	}
	
	async function fun() {
	    let a = await promise('我在定时器1里捏!!', 3000)
	    console.log(a);
	    let b = await promise('我在定时器2里捏!!', 2000)
	    console.log(b);
	    let c = await promise('我在定时器3里捏!!', 1000)
	    console.log(c);
	}
	
	fun()

在这里插入图片描述


总结

最后我们可以通过三张图片来直观对比一下三种写法:

1.回调地狱

在这里插入图片描述

2.Promise

在这里插入图片描述

3.async + await

在这里插入图片描述

注意

  • await 必须写在 async 函数中, 但 async 函数中可以没有 await
  • 在使用 await 的时候我们只是暂停了函数,而非整段代码

async/awaitPromise 并不存在谁代替谁的说法,因为 async/await 是寄生于 Promise、Generater 的语法糖。使用 async/await 可以实现用同步代码的风格来编写异步代码,而异步编程的最高境界就是不关心它是否是异步,async/await 很好的解决了这一点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/379113.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软件测试工程师——缺陷(一篇足以)

目录 定义 缺陷的类型 缺陷的严重程度 缺陷的状态 缺陷的根源 ​缺陷的来源 缺陷的起源 缺陷的生命周期 缺陷的识别 缺陷报告模板 编写缺陷报告的目的 缺陷报告编写的准则 缺陷描述的准则 定义 1. 软件未实现产品说明书中所提及的功能 2. 软件实现了产品说明书中…

stable_diffusion提示词编写笔记(1)

stable_diffusion提示词编写笔记(1) start 总结一下AI绘画学到的知识。 一.提示词分两种: 1.正向提示词; 2.反向提示词; 一个对应你希望图形包含的内容提示词,一个对应你不希望图形出现的内容提示词。 二.如何书写提示词 1.内…

连杆的形状优化

前言 本示例使用优化模块在不改变连杆体积的情况下将连杆中的应力集中降至最低。 本页讨论 前言应用描述Abaqus建模方法和仿真技术文件参考 应用描述 此示例说明了连杆的形状优化。形状优化对曲面节点在设计区域中的位置进行轻微修改,以实现优化的解决方案。形状优…

pwn学习笔记(2)ret_2_text_or_shellcode

pwn学习笔记(2) 1.三种常见的寄存器: ​ ax寄存器:通用寄存器,可用于存放多种数据 ​ bp寄存器:存放的是栈帧的栈底地址 ​ sp寄存器:存放的是栈顶的地址 2.栈帧与栈工作的简介&#xff1a…

Linux(Ubuntu)环境下安装卸载Python3(避免踩坑)

一、安装 第一步: 进入/usr/local/目录,下载Python3,这里我下载的是python 3.8.10,如果要下载其他版本改下链接中的版本号,需与官网版本号对应。 wget https://www.python.org/ftp/python/3.8.10/Python-3.8.10.tgz第…

HTML小白入门学习-表格标签

一、前言 话说上文&#xff0c;我们对HTML的表单类标签进行简单的学习和认识&#xff0c; 分别是<form>、<input>、<textarea>、<label>、<select>和<button>这几个标签。 与表单标签有一字之别的表格标签&#xff0c;就是本文的主角。本…

【MySQL】学习和总结DCL的权限控制

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-Bl9kYeLf8GfpdQgL {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Rating组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之Rating组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Rating组件 提供在给定范围内选择评分的组件。 子组件 无。 接口 Rating(opt…

整合RabbitMQ实现消息异步发送

消息队列中间件 消息队列中间件是分布式系统中重要的组件&#xff0c;主要解决应用耦合&#xff0c;异步消息&#xff0c;流量削峰等问题。 中间件最标准的用法是生产者生产消息传送到队列&#xff0c;消费者从队列中拿取消息并处理&#xff0c;生产者不用关心是谁来消费&#…

一个冷门的js加密逆向分析(二)

前天发了一片js加密分析的文章&#xff0c;今天继续来说第二层加密是什么样的。 上源代码 window["" "f" "3" "2" "0" "6" "b" "1" ""] function () {;(function (v509…

【html学习笔记】1.概念

1.概念 1.1 HTML标准格式 <html><body><p>Hello World</p></body> </html>1.2 编辑方式 新建一个笔记本文件&#xff0c;将html语法格式的内容写入。保存后将记事本的.txt后缀换成.html,就可以在浏览器里运行了 1.3 中文问题 为了避…

华为数通方向HCIP-DataCom H12-821题库(单选题:461-480)

第461题 以下关于路由策略特点的描述,错误的是哪一项? A、能够修改路由属性,但是不能改变网络流量经过的路径 B、能通过控制路由器的路由表规模,来节约系统资源 C、能通过控制路由的接收、发布和引入,以提高网络的安全性 D、能通过修改路由属性,对网络数据流量可以合理规…

SQL注入(SQL Injection)从注入到拖库 —— 简单的手工注入实战指南精讲

基本SQL注入步骤&#xff1a; 识别目标&#xff1a;确定目标网站或应用程序存在潜在的SQL注入漏洞。收集信息&#xff1a;通过查看页面源代码、URL参数和可能的错误信息等&#xff0c;搜集与注入有关的信息。判断注入点&#xff1a;确定可以注入的位置&#xff0c;比如输入框、…

跟着pink老师前端入门教程-day21+22

5.4 常见flex布局思路 5.5 背景线性渐变 语法&#xff1a; background: linear-gradient( 起始方向 , 颜色 1, 颜色 2, ...); background: -webkit-linear-gradient(left, red , blue); background: -webkit-linear-gradient(left top, red , blue); 背景渐变必须添加浏览…

【若依】若依框架在本地运行的操作方法,及踩坑记录

若依框架简介 若依是一个Gitee上一个开源的基于SpringBoot开发的轻量级Java快速开发框架&#xff0c;用以快速构建后台管理系统&#xff0c;点击跳转到官方地址 本机部署过程 Step1. 下载项目源码 我选择的是直接下载zip压缩包&#xff0c;解压后得到如下文件夹&#xff0c…

挑战杯 python opencv 深度学习 指纹识别算法实现

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python opencv 深度学习 指纹识别算法实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;4分创新点&#xff1a;4分 该项目较为新颖…

Java面试题(一)——MySQL索引、JVM内存模型、JDBC

1、mysql使用innodb引擎&#xff0c;请简述mysql索引的最左前缀如何优化 order by 语句&#xff1f; 1.1、核心回答 首先要对sql进行分析检查必要的查询字段&#xff0c;过滤字段&#xff0c;排序字段是否按顺序创建好了索引 如果查询字段不在索引中可能会产生回表操作会导致…

Linux环境下配置HTTP代理服务器教程

大家好&#xff0c;我是你们可爱的Linux小助手&#xff01;今天&#xff0c;我将带你们一起探索如何在Linux环境下配置一个HTTP代理服务器。请注意&#xff0c;这不是一次火箭科学的实验&#xff0c;而是一次简单而有趣的冒险。 首先&#xff0c;我们需要明确什么是HTTP代理服…

TOP100 二叉树(三)

11.114. 二叉树展开为链表 给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为 null 。展开后的单链表应该与二叉树 先序遍历 顺…

IoC原理

Spring框架的IOC是基于Java反射机制实现的&#xff0c;那具体怎么实现的&#xff0c;下面研究一下 反射 Java反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意方法…