Js异步,同步和内存模型

      很高兴可以和大家分享我的博客,这是我的第一篇博客。 由于之前在看Lambda表达式提到了闭包的概念,记得之前在前端有所耳闻,所以来研究前端一些技术。今天这里先来探讨有关Js运行机制的问题。

代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
<title>for</title>
    
</head>
<body>
	<button>11</button>
	<button>22</button>
	<button>33</button>
</body>
<script type="text/javascript">
     var btns = document.getElementsByTagName('button');  
          for (var i = 0; i < btns.length; i++) { 
				var btn = btns[i];
         		btn.onclick = function(){
					alert(i)
				}
			}
    
</script>
</html>

      这里抛出了一个小的例子,这个例子可能很多人都见过或者做过类似这样的题,运行之后我们分别点击三个button的时候弹出的数字都是3,并不是我们预期点击每个button弹出提示分别是0,1,2  的效果。我们要找到出现这样现象的原因在哪,首先我们要理解内存模型和几个概念。

Js单线程:

在浏览器的一个页面中,该页面的的Js只有一个线程(注意:Js是单线程,但浏览器内部并不是单线程,I/O、定时器、事件监听等都是浏览器的其他线程完成的),所以叫单线程。因为是单线程,所以程序的执行顺序都是从上到下依次进行的,同一时间内只能有一段代码被执行。

注意:提到一个js单线程的概念,但这里并没有说是同一个线程。也就说是一个线程但未必是同一个线程。这点理解尤为重要

任务队列和循环事件


Stack是栈存储同步任务,可以理解为不需要回调函数的操作。Heap是堆,存储对象等。Queen是任务队列存储异步任务。到这里我们不得不提出两个概念是同步和异步的概念

同步:对于一个工作任务,我们从上到下按1,2,3顺序执行,如果是同步代码,那么执行该任务的线程就一直被占用。

异步:对于一个工作任务,从上到下按1,2,3顺序执行,如果是异步代码,那么执行该任务的到1时,线程被回收到池子,其他人可以使用,当1执行完以后,从线程取出一个新的线程继续执行。这就是异步。这也就是我们上边提到的js所说的一个线程但是未必是同一个线程。

异步的出现是为了提高线程的利用率,让可用的线程更多,而不是一个线程只做一件事。讲完同步异步 我们继续说内存模型。

Queen任务队列。一旦异步任务有了响应,就会被push到任务队列。(点击事件,定时任务,服务响应等),每个异步任务都和一个回调函数关联。Js程序在Stack栈中执行同步任务(依照后进先出的顺序),随着Stack栈中任务被执行,当所有同步任务执行完,栈内存也就清空。接下来开始读取任务队列中的任务。并把与之相关联的回调函数压入Stack栈,单线程开始执行新的同步任务,执行完毕。


讲完上边的内存模型是不是我们认为之前的例子就很合理了,一个线程执行同步任务for循环到完毕,然后读取任务队列里的异步任务。然后把新的回调函数压入栈接着执行到完毕。

到这里第一篇博客就结束了,后续大部分是关于java 的总结,如果有机会可能会针对此博客再扩展讲解一下关于stack内存和Queen内存。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值