关闭

javascript中事件循环机制

标签: javascript视频
179人阅读 评论(0) 收藏 举报
分类:

JavaScript 的并发模型基于 “事件循环”。这个模型与像 C 或者 Java 这种其它语言中的模型着实不同。

运行时概念Edit

下面的内容解释了一个理论上的模型。现代 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 运行时包含了一个待处理的消息队列。每一个消息都与一个函数相关联。当栈为空时,从队列中取出一个消息进行处理。这个处理过程包含了调用与这个消息相关联的函数(以及因而创建了一个初始堆栈帧)。当栈再次为空的时候,也就意味着消息处理结束。

事件循环Edit

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

while (queue.waitForMessage()) {
queue.processNextMessage();
}
如果当前没有任何消息,queue.waitForMessage 会同步等待消息到来。

“执行至完成”
每一个消息执行完成后,其它消息才会被执行。当你分析你的程序时,这点提供了一些优秀的特性,包括当一个函数运行时,它不能被取代且会在其它代码运行前先完成(而且能够修改这个函数控制的数据)。这点与C语言不同。例如,C语言中当一个程序在一个线程中运行时,它可以在任何点停止且可以在其它线程中运行其它代码。

这个模型的一个缺点在于当一个消息的完成耗时过长,网络应用无法处理用户的交互如点击或者滚动。浏览器用“程序需要过长时间运行”的对话框来缓解这个问题。一个比较好的解决方案是使消息处理变短且如果可能的话,将一个消息拆分成几个消息。

添加消息
在浏览器里,当一个事件出现且有一个事件监听器被绑定时,消息会被随时添加。如果没有事件监听器,事件会丢失。所以点击一个附带点击事件处理函数的元素会添加一个消息。其它事件亦然。

调用 setTimeout 函数会在一个时间段过去后在队列中添加一个消息。这个时间段作为函数的第二个参数被传入。如果队列中没有其它消息,消息会被马上处理。但是,如果有其它消息,setTimeout 消息必须等待其它消息处理完。因此第二个参数仅仅表示最少的时间 而非确切的时间。

零延迟
零延迟 (Zero delay) 并不是意味着回调会立即执行。在零延迟调用 setTimeout 时,其并不是过了给定的时间间隔后就马上执行回调函数。其等待的时间基于队列里正在等待的消息数量。在下面的例子中,”this is just a message” 将会在回调 (callback) 获得处理之前输出到控制台,这是因为延迟是要求运行时 (runtime) 处理请求所需的最小时间,但不是有所保证的时间。

(function () {

  console.log('this is the start');

  setTimeout(function cb() {
    console.log('this is a msg from call back');
  });

  console.log('this is just a message');

  setTimeout(function cb1() {
    console.log('this is a msg from call back1');
  }, 0);

  console.log('this is the  end');

})();

// "this is the start"
// "this is just a message"
// "this is the end"
// "this is a msg from call back"
// "this is a msg from call back1"

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

绝不阻塞Edit

一个很有趣的事件循环 (event loop) 模型特性在于,Javascript 跟许多其它语言不同,它永不阻塞。通常由事件或者回调函数进行 I/O (input/output)处理 。所以当一个应用正等待 IndexedDB 的查询的返回或者一个 XHR 的请求返回时,它仍然可以处理其它事情例如用户输入。

例外是存在的,如 alert 或者同步 XHR,但应该尽量避免使用它们。注意,例外的例外也是存在的(但通常是实现错误而非其它原因)。

0
0
查看评论

详解 JavaScript 中的 Event Loop(事件循环)

前言     JavaScript 从诞生起就是一门单线程非堵塞的脚本语言。这是由其最初的用途来决定的:与浏览器交互。     单线程就是 js 代码在执行的时候只有一个主线程。     非堵塞就是 ...
  • huangpb123
  • huangpb123
  • 2018-01-19 11:12
  • 87

Javascript运行机制中的事件循环(Event Loop)

一.什么是Event Loop? 想要理解Event Loop,就要从程序的运行模式讲起。运行以后的程序叫做"进程"(process),一般情况下,一个进程一次只能执行一个任务。 如果有很多任务需要执行,不外乎三种解决方法。 (1)排队。因为一个进程一次只能执行一个任务,只好...
  • qq_34986769
  • qq_34986769
  • 2016-07-22 14:09
  • 315

JS:事件循环机制、调用栈以及任务队列

写在前面js里的事件循环机制十分有趣。从很多面试题也可以看出来,考察简单的setTimeout也就是考察这个机制的。 在之前,我只是简单地认为由于函数执行很快,setTimeout执行时间即便为0也不会马上输出,而是等待函数执行完后再输出。这只对了一半。 实际上其运行机制就是js中的事件循环机制...
  • qq_31628337
  • qq_31628337
  • 2017-05-01 15:40
  • 2676

事件循环机制

我们知道JavaScript的一大特点就是单线程,而这个线程中拥有唯一的一个事件循环。JavaScript代码的执行过程中,除了依靠函数调用栈来搞定函数的执行顺序外,还依靠任务队列(task queue)来搞定另外一些代码的执行。队列数据结构 一个线程中,事件循环是唯一的,但是任务队列可以拥有多个。...
  • u012193330
  • u012193330
  • 2017-04-01 10:46
  • 511

前端基础进阶(十二):深入核心,详解事件循环机制

Event Loop JavaScript的学习零散而庞杂,因此很多时候我们学到了一些东西,但是却没办法感受到自己的进步,甚至过了不久,就把学到的东西给忘了。为了解决自己的这个困扰,在学习的过程中,我一直试图在寻找一条核心的线索,只要我根据这条线索,我就能够一点一点的进步。 前端基础...
  • Fuohua
  • Fuohua
  • 2017-04-28 17:06
  • 409

Qt 事件循环机制 & 事件过滤器

在Qt中,事件被封装成一个个对象,所有的事件均继承自抽象类QEvent.  接下来依次谈谈Qt中有谁来产生、分发、接受和处理事件: 1、谁来产生事件: 最容易想到的是我们的输入设备,比如键盘、鼠标产生的 keyPressEvent,keyReleaseEvent,mousePressE...
  • xgy_123
  • xgy_123
  • 2014-03-09 16:55
  • 1960

JavaScript事件循环机制

JavaScript事件循环机制 1)、JavaScript的一大特点就是单线程 ,这个线程中拥有唯一的一个事件循环。 2)、JavaScript代码的执行过程中,除了依靠函数调用栈来处理函数的执行顺序外,还依靠任务队列来处理另外一些代码的执行。 3)、一个线程中,事件循环是唯一的,但是任务队列可...
  • qq1024884152
  • qq1024884152
  • 2017-04-06 21:42
  • 121

JavaScript事件驱动机制&定时器机制

在浏览器中,事件作为一个极为重要的机制,给予JavaScript响应用户操作与DOM变化的能力;在NodeJS中,异步事件驱动模型则是提高并发能力的基础。 一、程序如何响应事件 程序响应外部的事件有两种方式: 1. 中断 操作系统处理键盘等硬件输入就是通过中断来进行的,这个方式的好处是即使没有多...
  • ligang2585116
  • ligang2585116
  • 2015-07-03 11:37
  • 2370

Qt:事件和事件循环

最近想要了解一下Qt线程,但在对相关资料师都是从线程和事件循环开始将。对于事件循环是个相对很抽象的概念,研究了很久也很难在脑子里建立起一个具体的模型。今天在这里对这几天研究内容做总结,为以后做参考。      先说事件,网上很多资料都将的很清楚。在这里重点是明确一下一个...
  • cfqcfqcfqcfqcfq
  • cfqcfqcfqcfqcfq
  • 2016-05-05 11:05
  • 894

Nginx 事件循环

事件循环这个概念貌似在windows编程中提得更多,Linux程序却很少提及这个概念。本文所提及的事件循环其实就是worker cycle,由于此处将关注的不再是worker进程,而是worker进程在循环过程中关于事件处理的环节,因此就盗用了事件循环这个概念。在具体看代码前,先看一下这个“循环”的...
  • wangmanjie
  • wangmanjie
  • 2016-10-12 08:05
  • 213
    个人资料
    • 访问:10281次
    • 积分:299
    • 等级:
    • 排名:千里之外
    • 原创:17篇
    • 转载:17篇
    • 译文:0篇
    • 评论:0条