Promise, async, await 学习

异步编程简介:

介绍:异步编程是一种编程范式,旨在提高程序的性能和响应能力。该模型允许程序在执行某些任务时,不必等待这些任务完成就可以进行下一步操作,从而提高了程序的效率。

作用:异步编程通常用于涉及网络请求、文件读写、数据库查询等I/O密集型操作,以及高计算量的任务。在传统的同步编程中,这些操作会阻塞程序的执行,导致程序变慢或失去响应。而使用异步编程可以使这些I/O操作并行执行,从而提高程序的性能和响应能力。


并发 Concurrency、 并行 Parallelism、异步 Asynchronous、同步 Synchronous 的区别

(1)并发 Sancufrericy :代表计算机能够同时执行多项任务

计算机怎么做到并发 Concurrency 

(1)对于单核处理器,计算机可以通过分配时间片的方式——让一个任务运行一段时间,然后切换另外一个任务,再运行一段时间,不同的任务会这样交替往复的一直执行下去。——>这个过程也被称作是进程或者线程的上下文切换(context switching)

(2)对于多核处理器,可以在不同的核心上真正并行地执行任务,而不用通过分配时间片的方式运行——> 并行(parallelism)


同步和异步是两种不同的编程模型

(1)"同步” Synchronous 代表需要等到必须前一个任务执行完毕之后,才能进行下一个任务。因此在同步中并没有并发或者并行的概念。

(2)异步 Asynchronous 则代表不同的任务之间并不会相互等待、先后执行,即执行任务A时,也可以同时执行任务B

一个典型实现异步的方式则是通过多线程编程

多线程 Multithreoding : 创建多个线程并且启动他们,在多核的环境下,每个线程就会被分配到独立的核心上运行,实现真正的并行。

如果使用单核心处理器,或者通过设置亲和力(AfFnty) 强制将线程绑定到某个核心上

操作系统则会通过分配时间片的方式来执行这些线程,不过这些线程依然是在“并发”地执行Javascript 本身是没有多线程的概念的,不过通过它的函数回调(function callback)机制,依然能够做到单线程的“并发”。

例:通过 fetch() 函数 同时访问多个网络资源

⭕注意:

虽然主程序和回调函数看起来是同时进行的,但它们依然是运行在同一个线程中。

多线程编程、单线程的异步编程如何选择

(1)单线程的异步编程:对于I / O 密集的应用程序,比如 web 应用就会经常执行网络操作,数据库访问,这类应用就非常适合使用异步编程的方式。

如果是使用多线程的方式,则可能浪费系统资源(如下图)

因为每个线程的绝大多数时间都是在等待这些 I / O 操作,而线程自身会占用额外的内存(线程内存开销,线程切换开销还有线程资源竞争问题)

(2)多线程编程:

多线程编程则非常适合于计算量密集的应用,如视频图像处理,科学计算等。它能够让每一个 CPU 核心发挥最大的功效,而不是消耗在空闲的等待上。


JavaScript 中有两种实现异步的方式

(1)回调函数  Callback Function

可以使用 setTimeout() 让一个函数在指定的时间后执行,这个函数本身会立刻返回,程序紧接着会执行之后的代码,而传入的回调函数则会等到预定的时间才会执行

⭕注意:

  1. 这里的()=>是箭头表达式,相当于函数定义的简化写法
  2. Javascript 从设计之初就是一个单线程的编程语言 

即便看上去这里的回调函数和主程序在并发执行,但它们都运行在同一个主线程中。实际上主线程中还运行了我们写的其它代码,包括界面逻辑、网络请求、数据处理等等等等。虽然只有单个线程在执行,但这种单线程的异步编程方式其实有诸多优点。

由于所有操作都运行在同一个线程中,因此我们无须考虑线程同步或者资源竞争的问题,并且从源头上避免了线程之间的频繁切换。从而降低线程自身的开销。

缺点:

回调函数虽然简单好理解,但有一个明显的缺点:需要依次执行多个异步操作,会变成回调地狱 Callback Hell ——整个程序会一层接着一层的嵌套下去,可读性会非常差。


(2)Promise

Promise 就是为了解决这个问题——请求会在未来某个时刻返回数据,随后可以调用它的然后方法并传递一个回调函数。

Promise的API中的fetch就是很好的例子:

fetch 用来发起一个请求来获取服务器数据,可以用它动态更新页面的内容(即AJAX 技术 Asynchronous JavaScript and XML)

如果请求成功完成,则回调函数会被调起,请求的结果也会以参数的形式传递进来

而且  Promise的优点在于它可以用一种链式结构将多个异步操作串联起来!——链式调用 Chaining

response.json() 方法 也会返回一个 Promise,代表在未来某个时刻,将返回的数据转换成 JSON 格式。

如果想要等到它完成之后再执行其它的操作,可以在后面追加一个 then,然后执行接下来的代码。

Promise的链式调用避免了代码的层层嵌套,即便有很长的链,代码也不过是向下方增长而并非向右,因此可读性会提升不少。

使用异步操作也会遇到各种错误:各种网络问题或者返回的数据格式不正确等等

错误处理  Error Handling

如果想捕获这些错误,最简单的方法是附加一个 catch 在链式结构的末尾。

如果之前任意一个阶段发生了错误,那么将触发 catch ,之后的 then 将不会执行。这和同步编程中用到的 try/catch 块很类似。

类似的Promise还提供finally 方法,会在Promise 链结束之后调用。无论失败与否,都可以在这里做清理工作。

例如:如果我们用到了加载动画,则可以在这里关闭他。


新标准ECMA17 中加入的两个关键字 async、await

它们是基于 Promise之上的一个语法糖,使异步操作更加的简单。

首先我们需要使用 async 关键字将函数标记为异步函数。

异步函数就是指返回值为 Promise 对象的函数,比如之前用到的 fetch() 就是一个异步函数。

在异步函数中我们可以调用其它的异步函数,不过不再需要使用 then(),而是使用一个更加简洁的 await 语法。await 会等待 Promise 完成之后直接返回最终的结果。所以这里的 response 已经是服务器返回的响应数据了。

注意:await 虽然看上去会暂停函数的执行,但在等待的过程中,JavaScript 同样可以处理其它的任务,比如说更新界面,运行其他的代码等等。因为 await 底层是基于 Promise 和事件循环机制实现的。


await 使用时的陷阱

(1)分别去 await 这两个异步操作,虽然不存在逻辑错误,但这样写会打破这两个 fetch() 操作的并行。因为会等到第一个任务执行完成之后才开始执行第二个任务。

因此更高效的做法是将所有 Promise 用 Promise.all 组合起来。

 


(2)如果需要在循环中执行异步操作,是不能够直接调用 forEach 或者 map 这一类方法的,尽管我们在回调函数中写了 await,但这里的 forEach 会立刻返回,它并不会暂停等到所有异步操作都执行完毕

 如果我们希望等待循环中的异步操作都一一完成之后才继续执行,那我们还是应当使用传统的 for 循环。

更进一步,如果我们想要循环中的所有操作都并发执行 ——> for await

这里的 for 循环依然会等到所有的异步操作都完成之后才继续向后执行 。


(3)不能在全局或者普通函数中直接使用 await 关键字,await 只能被用在异步函数(asyncfunction)中。

如果我们想在最外层中使用 await,那么需要先定义一个异步函数,然后在函数体中使用它。

使用async和await 可以让我们写出更清晰、更容易理解的异步代码,因此我们几乎不再需要使用底层的Promise 对象

包括调用它的then() ,catch()函数等等。

即便是对于某些旧版本的浏览器(例如IE)不支持async语法 ,我们还是可以使用转译器将它们编译成旧版本也兼容的等效代码。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python常用功能的标准代码

后台运行并保存log 1 2 3 4 5 6 7 8 9 nohup python -u test.py > test.log 2>&1 & #最后的&表示后台运行 #2 输出错误信息到提示符窗口 #1 表示输出信息到提示符窗口, 1前面的&注意添加, 否则还会创建一个名为1的文件 #最后会把日志文件输出到test.log文…

使用python-opencv检测图片中的人像

最简单的方法进行图片中的人像检测 使用python-opencv配合yolov3模型进行图片中的人像检测 1、安装python-opencv、numpy pip install opencv-python pip install numpy 2、下载yolo模型文件和配置文件: 下载地址: https://download.csdn.net/down…

集群化环境前置准备

目录 部署 1. 配置多台Linux虚拟机 1.1 首先,关机当前CentOS系统虚拟机(可以使用root用户执行init 0来快速关 机) 1.2 新建文件夹 1.3 克隆 1.4 同样的操作克隆出:node2和node3 1.5 开启node1,修改主机名为node1&…

活动报名与缴费小程序开发笔记一

项目背景 活动报名与缴费小程序的开发背景主要源于以下几个因素: 1.数字化时代的需求: 随着移动互联网和智能手机的普及,人们习惯使用手机进行各种活动。传统的纸质报名表格和线下缴费方式变得相对繁琐,而数字化报名与缴费小程序…

【小沐学前端】Node.js实现基于Protobuf协议的UDP通信(UDP/TCP)

文章目录 1、简介1.1 node1.2 Protobuf 2、下载和安装2.1 node2.2 Protobuf2.2.1 安装2.2.2 工具 3、node 代码示例3.1 HTTP3.2 UDP单播3.4 UDP广播 4、Protobuf 代码示例4.1 例子: awesome.proto4.1.1 加载.proto文件方式4.1.2 加载.json文件方式4.1.3 加载.js文件方式 4.2 例…

gorm 自定义时间、字符串数组类型

文章目录 自定义时间类型自定义字符串数组测试与完整代码测试代码测试结果 GORM 是GO语言中一款强大友好的ORM框架,但在使用过程中内置的数据类型不能满足以下两个需求,如下: time.Time类型返回的是 2023-10-03T09:12:08.5352808:00这种字符串…

FreeRTOS入门教程(队列详细使用示例)

文章目录 前言一、队列基本使用二、如何分辨数据源三、传输大块数据总结 前言 上篇文章我们已经讲解了队列的概念和队列相关的API函数,那么本篇文章的话就开始带大家来学习使用队列。 一、队列基本使用 这个例子将会创建三个任务,其中两个任务用来发送…

完美清晰,炫酷畅享——Perfectly Clear Video为你带来卓越的AI视频增强体验

在我们日常生活中,我们经常会拍摄和观看各种视频内容,无论是旅行记录、家庭聚会还是商务演示,我们都希望能够呈现出最清晰、最精彩的画面效果。而现在,有一个强大的工具可以帮助我们实现这一目标,那就是Perfectly Clea…

谁“动”了我的信息?

通信公司“内鬼” 批量提供手机卡 超6万张手机卡用来发涉赌短信 2023年10月2日,据报道2022年12月,湖北省公安厅“雷火”打击整治治安突出问题专项行动指挥部研判发现,有人在湖北随州利用虚拟拨号设备GOIP发出大量赌博短信。随州市公安局研判…

【数据结构--八大排序】之快速排序

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …

Flink--9、双流联结(窗口联结、间隔联结)

星光下的赶路人star的个人主页 我还有改变的可能性,一想起这点,我就心潮澎湃 文章目录 1、基于时间的合流——双流联结(Join)1.1 窗口联结(Window Join)1.2 间隔联结(Interval Join)…

苹果手机怎么备份所有数据?2023年iPhone 15数据备份常用的3种方法!

当苹果手机需要进行刷机、恢复出厂设置、降级iOS系统等操作时,我们需要将自己的iPhone数据提前进行备份。 特别是在苹果发布新iOS系统时,总有一些小伙伴因为升降级系统,而导致了重要数据的丢失。 iPhone中储存着重要的照片、通讯录、文件等数…

出去重复的列值(关键词:distinct)

MySQL从小白到总裁完整教程目录:https://blog.csdn.net/weixin_67859959/article/details/129334507?spm1001.2014.3001.5502 语法格式: select distinct 列名 from 表名; 案例:查询emp表中,员工的职位(job),并去重…

Redis-分布式锁

分布式锁相关内容 超卖问题切入可以使用互斥锁给先获取到锁的线程加锁吗?使用redis分布式锁解决超卖问题setnx命令实现分布式锁为什么需要设置过期时间?Redis实现分布式锁如何合理控制锁的有效时长 redisson实现分布式锁 超卖问题切入 我们先来看一个项目…

【Docker内容大集合】Docker从认识到实践再到底层原理大汇总

前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助。 高质量博客汇总https://blog.csdn.net/yu_cblog/categ…

前端TypeScript学习day01-TS介绍与TS部分常用类型

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 TypeScript 介绍 TypeScript 是什么 TypeScript 为什么要为 JS 添加类型支持? TypeScript 相…

【已解决】spring-boot项目使用maven打包时出现BOOT-INF文件夹的问题

jar中多了这个BOOT-INF文件夹的原因,主要是因为我们在maven的pom文件中加入了spring-boot-maven-plugin这个插件,如下所示: 只需要将加个configuration标签,并在里面嵌套加入一个skip子标签,并将skip的值设为true&…

vulnhub靶机doubletrouble

下载地址:doubletrouble: 1 ~ VulnHub 主机发现 arp-scan -l 端口扫描 nmap --min-rate 1000 -p- 192.168.21.151 端口服务扫描 nmap -sV -sT -O -p22,80 192.168.21.151 漏洞扫描 nmap --scriptvuln -p22,80 192.168.21.151 先去看看web页面 这里使用的是qdpm …

如何一步步优化负载均衡策略

发展到一定阶段后,Web 应用程序就会增长到单服务器部署无法承受的地步。这时候企业要么提升可用性,要么提升可扩展性,甚至两者兼而有之。为此,他们会将应用程序部署在多台服务器上,并在服务器之前使用负载均衡器来分配…

pycharm配置python3.8版本专门用于undecteded_chromedriver测试

pycharm配置python3.8版本专门用于undecteded_chromedriver测试 作者:虚坏叔叔 博客:https://pay.xuhss.com 早餐店不会开到晚上,想吃的人早就来了!😄 一、Pycharm及python环境的配置 1.安装python-3.8.7rc1-amd64.e…