JavaScript并发模型和事件循环

来源:互联网 发布:银行家算法实验分析 编辑:程序博客网 时间:2024/06/05 03:09

javascript的并发模型基于事件循环。javascript是一个单线程模型。
此模型的确定:
这个模型的一个缺点在于当一个消息的完成耗时过长,网络应用无法处理用户的交互如点击或者滚动。

运行时概念

可视化描述

这里写图片描述

函数调用形成了一个栈帧。

 function foo(b) {  var a = 10;  return a + b + 11;}function bar(x) {  var y = 3;  return foo(x * y);}console.log(bar(7));

当调用 bar 时,创建了第一个帧 ,帧中包含了 bar 的参数和局部变量。当 bar 调用 foo 时,第二个帧就被创建,并被压到第一个帧之上,帧中包含了 foo 的参数和局部变量。当 foo 返回时,最上层的帧就被弹出栈(剩下 bar 函数的调用帧 )。当 bar 返回的时候,栈就空了。

对象被分派在堆中。

队列

一个javascript运行时包含了一个待处理的消息队列。每个消息都与一个函数关联。当栈为空的时候,从队列中取出一个消息进行处理。这个处理过程包含了调用与这个消息相关联的函数。当栈再次为空的时候,意外这消息处理结束。

事件循环

之所以被称为事件循环,因为它经常被用于如下类似的方式来实现:

 while (queue.waitForMessage()) {  queue.processNextMessage(); }

如果当前没有任何消息到来。queue.waitForMessage()会同步阻塞等待消息到来。

执行至完成

每一个消息执行完成后,其它消息才会被执行。当你分析你的程序时,这点提供了一些优秀的特性,包括当一个函数运行时,它不能被取代且会在其它代码运行前先完成。

零延迟

零延迟 (Zero delay) 并不是意味着回调会立即执行。在零延迟调用 setTimeout 时,其并不是过了给定的时间间隔后就马上执行回调函数。其等待的时间基于队列里正在等待的消息数量。

多个运行时互相通信

一个 web worker 或者一个跨域的 iframe 都有它们自己的栈,堆和消息队列。两个不同的运行时只有通过 postMessage 方法进行通信。这个方法会给另一个运行时添加一个消息如果后者监听了 message 事件。

绝不阻塞

一个很有趣的事件循环(event loop)模型特性在于:Javascript跟其他语言不同,它永不阻塞,通常由事件或者回调函数I/0(input /output)处理。

原创粉丝点击