被说一知半解,await不懂你别乱用

article/2025/9/14 9:36:53

文章目录

      • 1.前言
      • 2.await是否阻塞主线程?
      • 3.await是否同步?
      • 4.总结

1.前言

这篇文章我是不想写的,因为之前已经写过了(异步回调Async Await与Promise区别),此时此刻的心情是非常的不满,为什么呢? 因为前几天项目中把多层promise链式回调用了用 es6的await改写了,当我们前端XXX看到之后很疑惑,就问,为什么这么写?你知道await是什么吗?我说知道,await后面是返回的一个promise的resolve/reject的结果,这样的目的可以避免很多promise链式嵌套回调,而且await 的promise不执行完,下面代码也不会执行!代码看上去也很同步,他很不屑的看了我一眼,别一知半解的在那乱用(我们公司的领导说话口气都这样),别以为我不懂,这个await就是等待的意思!它就是个同步代码,会阻塞主线程,以前写什么XXX的时候,用这个会导致浏览器卡死不动,在后端服务器会直接DOWN掉,不知道不要乱用?,其实我很想解释,但是我觉得当时的情况,我多说无益,其实我这样写也是为了让代码更加清晰,以后维护起来也方便!无奈之举!只能改回promise的链式嵌套写法,这篇文章我会分析下我对await(一知半解)的理解!

2.await是否阻塞主线程?

先说下 await的正确使用,await必须是在这个async声明的函数内部使用,async是什么意思?异步的意思,看到这个东西也知道这个是个异步的函数,会阻塞主线程?,javascript虽然是单线程,先执行同步代码,碰到异步函数的会扔进异步队列里面,等主线程空闲了再把异步队列再把异步函数放进主线程执行,下面我来证实下我的观点

let test = async () =>{return await new Promise((resolve, reject)=>{setTimeout(() =>{resolve("第一个请求")console.log("第一个请求")}, 5000)});
}test();for (let i = 0; i < 10; i++) {setTimeout((i) =>{console.log("我执行了" + i + "次")}, 1000 * i, i);
}

按正常执行顺序,主线程执行到test函数时,如果是同步的,那么下面的for循坏更本不会执行!我们来看执行结果

在这里插入图片描述
结论:所以可以跟明确的得出结论,它不会阻塞主线程!


3.await是否同步?

首先要明白await的用法,当await后面的不是promise,它会不会阻塞?看下面代码!

function forLoop() {for (let i = 0; i < 10; i++) {setTimeout((i) =>{console.log("我执行了" + i + "次")}, 1000 * i, i);}
}let test = async () => {await forLoop();console.log("我执行不执行");
}
test();

await 后面不是个promise,而是个for循环,里面有个setTimout,这个又涉及到宏任务了(先不管,暂且他看成异步),那么await 后面接到一个异步setTimout的函数,那么我下面的 console.log还会执行吗?还是会卡在这里,等setTimout函数执行完再执行呢?让结果来告诉我们!
在这里插入图片描述
结论:如果await后面接的不是promise,那么它是按正常顺序执行的,先同步后异步,需要注意的await后面属于微任务,所以,这种情况也不会阻塞

如果await 后面接的是promise,那么await后面的代码就相当在promise.then()里面执行,promise.then里面是个微任务如果不懂可以点击javascript执行机制所以我们来看下例子回忆下

setTimeout(() => {console.log("setTimeout宏任务")
}, 0);let test = async () =>{console.log("promise 同步代码1")let onePromise = await new Promise((resolve, reject) => {resolve("success")});console.log("promise微任务执行2");
}test();new Promise((resolve, reject) => {console.log("promise 同步代码")resolve("success");
}).then((data) => {console.log("promise微任务执行1")
})
console.log("end");

简单分析下,一开始setTimeout宏任务扔进任务队列,接着执行console.log("promise 同步代码1"), console.log("promise微任务执行2")是在promise.then中执行的所以是个微任务扔进任务队列,接着执行 console.log("promise 同步代码"), 又一个 console.log("promise微任务执行1") 微任务扔进任务队列,接着执行console.log("end"),看下任务队列有没有微任务,按顺序执行 console.log("promise微任务执行2"),再执行 console.log("promise微任务执行1"),最后执行下一轮事件循环,执行 console.log("setTimeout宏任务"),后面没有微任务了,结束事件循环!
在这里插入图片描述

let test = async () => {let onePromise = await new Promise((resolve, reject) => {resolve("success")});let result = "promise微任务执行2" ;console.log(result); 
}test();//等价于let test = async () => {let onePromise = await new Promise((resolve, reject) => {resolve("success")});
}
test().then((data)=>{let result = "promise微任务执行2" ;console.log(result);
});

await 后面的执行都相当于放到了Promise.resolve(),很显然是成功的回调函数!那么多个await呢?我们来模拟下

let asyncFn1 = async () => {await new Promise((resolve, reject) => {resolve("success1")console.log("success1");});await new Promise((resolve, reject) => {resolve("success2")console.log("success2");});await new Promise((resolve, reject) => {resolve("success3");console.log("success3");});
}
asyncFn1();//等价于let asyncFn1 = async () => {await new Promise((resolve, reject) => {resolve("success1")console.log("success1");});
}
asyncFn1().then((data) => {let asyncFn2 = async () => {await new Promise((resolve, reject) => {resolve("success2")console.log("success2");});}asyncFn2().then(() => {let asyncFn3 = async () => {await new Promise((resolve, reject) => {resolve("success3")console.log("success3");});}asyncFn3().then(() => {})});
});

在这里插入图片描述

看上面这种代码转变,那么你应该知道这个和promise链式调用有没有什么区别?为什么es6要出async,await,就是为了解决这种多个promise链式调用嵌套的,它是promise的升级版!只是在promise原有的基础上升级了,让我们调用的时候代码看起来更清晰!

let asyncFn1 = async () => {let onePromise = await new Promise((resolve, reject) => {setTimeout(function () {resolve("第一个请求");console.log("第一个请求");}, 5000)});console.log("我要先执行");
}asyncFn1();

像上面这种写法是有问题,要等onePromise 执行完成之后才会执行下面的,但是你别忘记了await的初衷,你肯定不会愚蠢到把先要执行的东西放到一个promise的回调里面吧

结论:如果await后面接的是promise,那么它是严格按照代码顺序执行的,此时是同步的,因为后面的代码都是promise的成功回调


4.总结

await不会阻塞主线程,不会导致浏览器假死,卡死,anync是个异步函数,会被放进异步队列,等主线程空闲了才会放进主线程,await后面的代码如果是promise,那么是同步的,如果不是promise,那么执行规则是先同步后异步,但是你要了解await,它是为了解决promise链式调用嵌套而存在的,就算是promise链式嵌套,它的执行也是同步!所以要在合适的使用场景正确使用!(你可能写个循环都会出现死循环导致浏览器崩溃)


http://chatgpt.dhexx.cn/article/lB0NG2uE.shtml

相关文章

async、await详解

一、async/await是什么&#xff1f; 简而言之&#xff0c; async用于申明一个function是异步的&#xff1b; 而await则可以认为是 async await的简写形式&#xff0c;是等待一个异步方法执行完成的。 二、async和await的基础使用 async/awiat的使用规则: async 表示这是一个a…

理解异步函数async和await的用法

定义 1. async 是异步的意思&#xff0c;await则可以理解为 async wait。所以可以理解async就是用来声明一个异步方法&#xff0c;而 await是用来等待异步方法执行 2. async作为一个关键字放在函数前面&#xff0c;表示该函数是一个异步函数&#xff0c;异步函数意味着该函数的…

(一)概述:NGS测序在病原微生物检测中的应用

❝ NGS 技术在临床上的应用逐步趋于成熟&#xff0c;从早期的肿瘤基因检测&#xff0c;到如今大热的微生物病原核酸检测&#xff0c;NGS 技术以其快速、准确和高分辨率的特点&#xff0c;发挥着无可替代的作用。 ❞ 微生物在地球上无处不在&#xff0c;从陆地到海洋&#xff0c…

肿瘤NGS测序公司生信工程师水平划分

生信工程师能力划分 1、大头兵&#xff08;1&#xff09;初级生信工程师工作职责任职要求 &#xff08;2&#xff09;中级生信工程师工作职责任职要求 &#xff08;3&#xff09;高级生信工程师工作职责任职要求 2、主管/经理职位描述任职要求 3、总监参考资料&#xff1a; 去年…

NGS数据分析实践:04. 准备测序数据

NGS数据分析实践&#xff1a;04. 准备测序数据 文接上篇&#xff1a;NGS数据分析实践&#xff1a;03. 涉及的常用数据格式[5] - vcf格式 本次NGS数据&#xff0c;采用多重PCR靶向扩增子测序技术&#xff0c;在Illunima Hiseq X Ten测序平台上进行双末端&#xff08;paired-end…

NGS_panel的CAP认证学习笔记

对于基因的定义总体可以划分为两类 GAD: Gene associated with Mendelian disorder; GADs include genes that meet criteria for definitive, strong, or moderate evidence for association with disease as described by ClinGenGUS: Gene of uncertain significance; GUSs …

45万例患者基因检测显示:NGS很难检测出七分之一的致病变异

基于下一代测序&#xff08;NGS&#xff09;的临床基因测试越来越多地用于辅助诊断&#xff0c;针对该技术的临床应用有具体的指南&#xff0c;除了检测相对可靠的单核苷酸变异&#xff08;SNVs&#xff09;和微小插入缺失&#xff08;indel&#xff09;&#xff0c;NGS也已经被…

R实战 | NGS数据时间序列分析(maSigPro)

masigpro 跟着Cell学作图 | 6.时间序列分析(Mfuzz包) 一个答疑教程。 maSigPro 流程 示例数据 #BiocManager::install(maSigPro) library(maSigPro) # 载入示例数据 data(data.abiotic) data.abiotic[1:5,1:5] data(edesign.abiotic) head(edesign.abiotic) > data.abiotic…

NGS数据分析实践:03. 涉及的常用数据格式[5] - vcf格式

NGS数据分析实践&#xff1a;03. 涉及的常用数据格式[5] - vcf格式 6. vcf格式6.1 vcf格式整体描述6.2 第8列INFO详解6.3 第9列FORMAT详解6.4 vcf文件简单解读 系列文章&#xff1a; 二代测序方法&#xff1a;DNA测序之靶向重测序 NGS数据分析实践&#xff1a;00. 变异识别的基…

生信小白学习日记Day4Day5——NGS基础 NGS分析注释(BWA软件)

2019年5月30日&#xff0c;晚上&#xff0c;心情变好&#xff0c;好几天没更新了&#xff0c;看到男朋友在学一款软件&#xff0c;我也近朱者赤&#xff0c;来继续注释Day2-2中NGS分析流程中的一个重要软件——BWA NGS基础 NGS分析注释 BWA 对应于NGS分析流程的这两步&…

NGS数据分析实践:00. 变异识别的基本流程

NGS数据分析实践&#xff1a;00. 变异识别的基本流程 变异识别过程可以分成3大块&#xff1a;1. 原始数据质控&#xff1b;2. 数据预处理&#xff1b;3. 变异识别。大致可以细分为6个部分&#xff1a;(1) 原始测序数据的质控&#xff1b;(2) read比对&#xff0c;排序和标记PCR…

如何用软件模拟NGS数据

如何用软件模拟NGS数据 为了评价一个工具的性能&#xff0c;通常我们都需要先模拟一批数据。这样相当于有了参考答案&#xff0c;才能检查工具的实际表现情况。因此对于我们而言&#xff0c;面对一个新的功能&#xff0c;可以先用模拟的数据测试下不同工具的优缺点。有如下几个…

生信小白学习日记Day2——NGS基础 illumina高通量测序原理

2019年5月26日&#xff0c;周日&#xff0c;小雨 说明&#xff1a;阅读生信宝典和查阅文章的总结&#xff0c;原文请关注公众号生信宝典&#xff0c;参考的博文都附有链接&#xff0c;仅供参考。 生信宝典 NGS基础——高通量测序原理 本文介绍了测序文库构建原理、链特异性文…

NGS数据分析实践:05. 测序数据的基本质控 [2] - MultiQC

NGS数据分析实践&#xff1a;05. 测序数据的基本质控 [2] - MultiQC 2. MultiQC2.1 帮助信息及运行代码2.2 报告解读2.3 小结 文接上篇&#xff1a;NGS数据分析实践&#xff1a;05. 测序数据的基本质控 [1] - FastQC 2. MultiQC NGS技术的进步催生了新的实验设计、分析类型和极…

NGS数据分析实践:03. 涉及的常用数据格式[2] - sam/bam格式

NGS数据分析实践&#xff1a;03. 涉及的常用数据格式[2] - sam/bam格式 2. sam和bam格式 系列文章&#xff1a; 二代测序方法&#xff1a;DNA测序之靶向重测序 NGS数据分析实践&#xff1a;00. 变异识别的基本流程 NGS数据分析实践&#xff1a;01. Conda环境配置及软件安装 NGS…

NGS数据过滤之trimmomatic

NGS 原始数据过滤对后续分析至关重要&#xff0c;去除一些无用的序列也可以提高后续分析的准确率和效率。Trimmomatic 是一个功能强大的数据过滤软件。 Trimmomatic 介绍 Trimmomatic 发表的文章至今已被引用了 2810 次&#xff0c;是一个广受欢迎的 Illumina 平台数据过滤工具…

NGS基础:测序原始数据批量下载

生物或医学中涉及高通量测序的论文&#xff0c;一般会将原始测序数据上传到公开的数据库&#xff0c;上传方式见测序文章数据上传找哪里&#xff1b;并在文章末尾标明数据存储位置和登录号,如 The data from this study was deposited in NCBI Sequence Read Archive under acc…

NGS之数据格式

生物信息中常见的几种数据格式有:fasta、fastq、bam、sam、vcf、bed、gff。 参考&#xff1a;http://www.biotrainee.com/thread-42-1-1.html FASTQ 参考&#xff1a;https://en.wikipedia.org/wiki/FASTQ_format fastq格式是文本格式。它有对应序列字符的质量分数&#xff…

生信小白学习日记Day3——NGS基础 NGS分析注解(质量分析软件)

2019年5月27日&#xff0c;天气舒适&#xff0c;忙碌一天之后开始今天的生信学习。今天就昨天Day2-2的一些标记加以查询说明&#xff0c;仅供参考。 NGS基础 NGS分析注解 1. 质量分析软件 昨天提到&#xff0c;拿到数据后可以通过一些软件来评估测序质量的好坏&#xff0c;…

NGS 数据过滤之 Trimmomatic

NGS Trimmomatic 支持多线程&#xff0c;处理数据速度快&#xff0c;主要用来去除 Illumina 平台的 Fastq 序列中的接头&#xff0c;并根据碱基质量值对 Fastq 进行修剪。软件有两种过滤模式&#xff0c;分别对应 SE 和 PE 测序数据&#xff0c;同时支持 gzip 和 bzip2 压缩文…