一篇文章彻底搞懂异步,同步,setTimeout,Promise,async「建议收藏」

一篇文章彻底搞懂异步,同步,setTimeout,Promise,async「建议收藏」之前翻看别的大佬的博客看到了关于setTimeout,promise还有async执行顺序的文章。观看了几篇之后还是没有怎么看懂,于是自己开始分析代码,并整理了此文章,我相信通过此文章朋友们能对异步同步还有,setTimeout,Promise,async这些内容了然于胸,接下来让我们走入正题:…

大家好,又见面了,我是你们的朋友全栈君。

感谢内容提供者:金牛区吴迪软件开发工作室

之前翻看别的大佬的博客看到了关于setTimeout,promise还有async执行顺序的文章。观看了几篇之后还是没有怎么看懂,于是自己开始分析代码,并整理了此文章,我相信通过此文章朋友们能对异步同步还有,setTimeout,Promise,async这些内容了然于胸,接下来让我们走入正题


这是别的大佬博客里面的代码:

async function async1() { 
   
   console.log('async1 start')
   await async2()
   console.log('async1 end')
}
async function async2() { 
   
   console.log('async2')
}
console.log('script start')
setTimeout(() => { 
   
	console.log('setTimeout')
},0)
async1()
new Promise((resolve) => { 
   
	console.log('promise1')
	resolve()
}).then(() => { 
   
	console.log('promise2')
})
console.log('script end')

执行结果(不同浏览器执行结果可能不同,笔者用的谷歌):
在这里插入图片描述

PS:下面的关键点笔者都用加粗给朋友们圈起来了哦,请仔细观看

笔者这时候开启了双屏模式,看它的这个代码的执行结果去猜它的规律,然后再看MDN文档,结果就一目了然了。
我们现在一起来分析代码:
在这里插入图片描述
这只是定义了俩个异步函数(),并没有调用,所以暂时不用管。

在这里插入图片描述
这是同步的内容,所以会直接执行

1.输出 script start

在这里插入图片描述
setTimeout是一个计时器,异步的,所以被扔到了任务队列里面,暂时不去管,我们只需要记住异步队列里面有他就可以。

在这里插入图片描述
调用了async1函数,会走入到这个函数里,我们先再看一下这个函数:
PS:注意点:
当调用async函数的时候会返回一个Promise对象
。Promise对象是立即执行的,后面会详细介绍。

在这里插入图片描述
这时候会

2.输出async1 start,

而后到了await async2()
这里需要注意一下,在async里遇到await它会使async函数暂停执行,执行完async里的await内容后将后续的内容扔入到浏览器的任务队列里面去。
所以这里输出了async1 start后又

3.输出了async2

async2执行完毕之后又走回到调用了async1的位置。将async1没有执行的部分扔到了任务队列里面去。(现在任务队列里面有一个setTimeout和一个async1的后续内容)

接下来又走到了Promise:
在这里插入图片描述
Promise是立即执行的,所以它会立即

4.输出promise1。

而后是执行了resolve。执行成功,执行成功的话会走入promise的.then方法里,可是它是异步的回调函数,所以会被丢入到任务队列里。(现在任务队列里面有一个setTimeout和一个async1的后续内容在加上promise的.then内容)

最后走到了:
在这里插入图片描述
因为它是同步的,所以会直接执行。

5.输出:script end

前五个我们都分析完毕了,接下来到关键点了:
现在异步队列中有三个任务分别是:

  • setTimeout
  • async1的后续内容
  • promise的.then内容

这三个内容setTimeout会在最后执行,就好比css权重的优先级,大家固定记住就可以,setTimeout的优先级没有async和promise级别高(其实async和promise是一样的,因为调用async方法时就是返回一个promise对象
而后async和promise的.then就看谁先进入到的任务队列里面,任务队列里面有先进先出的概念。所以结果很明显了,它们三个的输出顺序是:
6.输出:async1 end
7.输出:promise2
8.输出:setTimeout

在给朋友们随便写一个代码,大家一起猜一下执行结果会是什么:
setTimeout(() => { 
   
	console.log('setTimeout')
}, 0)
console.log('t1')
fetch('http://dict.qq.com')
 .then(function(response) { 
   
   return response.json();
 })
 .then(function(myJson) { 
   
   console.log('myJson');
 })
 .catch(function(err) { 
   
 	console.log(err)
 })
console.log('fetch zhi hou')
async function async1() { 
   
	console.log('async1 start')
	await async2()
	console.log('async1 end')
}
async1()
console.log('t2')
new Promise((resolve) => { 
   
	console.log('promise')
	resolve()
}).then(() => { 
   
	console.log('promise.then')
})
console.log('t3')
async function async2() { 
   
	console.log('async2')
}
console.log('t4')

执行结果:
在这里插入图片描述

小总结:

其实这个就是涉及了JavaScript的Event Loop【事件循环】
在这里插入图片描述
上图就是JS事件循环的全过程。

执行全局Script同步代码,这些同步代码有一些是同步语句,有一些是异步语句(比如setTimeout等);
全局Script代码执行完毕后,调用栈Stack会清空;
从微队列microtask queue中取出位于队首的回调任务,放入调用栈Stack中执行,执行完后microtask queue长度减1;
继续取出位于队首的任务,放入调用栈Stack中执行,以此类推,直到直到把microtask queue中的所有任务都执行完毕。注意,如果在执行microtask的过程中,又产生了microtask,那么会加入到队列的末尾,也会在这个周期被调用执行;
microtask queue中的所有任务都执行完毕,此时microtask queue为空队列,调用栈Stack也为空;
取出宏队列microtask queue中位于队首的任务,放入Stack中执行;
执行完毕后,调用栈Stack为空;
重复第3-7个步骤;
重复第3-7个步骤;

1.宏队列microtask一次只从队列中取一个任务执行,执行完后就去执行微任务队列中的任务;
2.微任务队列中所有的任务都会被依次取出来执行,直道microtask queue为空;
3.图中没有画UI rendering的节点,因为这个是由浏览器自行判断决定的,但是只要执行UI rendering,它的节点是在执行完所有的microtask之后,下一个macrotask之前,紧跟着执行UI render。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/158233.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • ubuntu安装wget命令_linux bash命令

    ubuntu安装wget命令_linux bash命令我们先安装linux系统比如centos7.1里面有的就没有wget下载工具。wget这个命令就不可以使用。我们使用yum-yinstallwgetyuminstallperl会出现:[root@localhost~]#yum-yinstallwgetLoadedplugins:fastestmirrorRepodataisoverweeksold.Instal…

    2022年10月16日
  • Tesseract OCR初探

    Referfromhttp://hellosure.github.io/ocr/2014/10/11/tesseract-ocr/11October2014OPENCV&OCROpenCV(OpenSourceComputerVisionLibrary,跨平台计算机视觉库),专注机器视觉,是个更大范围的概念OCR(OpticalCh

  • 2021DIY电脑配置入门篇(包含各cpu显卡天梯图对比)

    2021DIY电脑配置入门篇(包含各cpu显卡天梯图对比)前言:我本来以为一篇文章可以把电脑配置讲清楚的,但是发现电脑比我想象的要复杂,所以可能分了几篇来写如何查看自己的电脑配置最简单的右键桌面此电脑->点击属性下载个电脑管家等电脑助手软件也可以查看详细配置如何DIY自己的第一台电脑篇幅有限,这里我只详细分析一台电脑的核心配置(CPU、主板、显卡),外加内存定好预算对于电脑来说,预算是最重要的!没有预算,一切都是空谈。没预算默认外星人Area51M(价格在2万左右),现在电脑往往充当一种娱乐需求,相对来说比较次要,因此大多数人配电脑.

  • 前端实现异步的几种方式_redux是什么

    前端实现异步的几种方式_redux是什么1.什么是Saga?实际上,这个术语出自康奈尔大学的一篇论文:http://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf最初这篇论文是为了解决分布式系统中的LLT(LongLivedTransaction),也就是长时运行事务的数据一致性问题的。这么说有点抽象,我们来举个具体的例子:假如你在一个在线订票系统上订了一张…

  • k8s 资源管理_k8s扩容命令

    k8s 资源管理_k8s扩容命令k8s管理器介绍yaml资源管理器介绍管理器介绍在Kubernetes中,所有的内容都抽象为资源,用户需要通过操作资源来管理Kubernetes。Kubernetes的本质就是一个集群系统,用户可以在集群中部署各种服务。所谓的部署服务,其实就是在Kubernetes集群中运行一个个的容器,并将指定的程序跑在容器中。Kubernetes的最小管理单元是Pod而不是容器,所以只能将容器放在Pod中,而Kubernetes一般也不会直接管理Pod,而是通过Pod控制器来管理Pod的。Pod提供服务之后

  • ArcEngine 中的-2147467259错误

    ArcEngine 中的-2147467259错误ArcEngine中因数据不合规导致的-2147467259错误

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号