定时器运行原理 && javascript事件循环模型

  定时器是我们经常使用的一个异步函数,它的用处十分广泛,比如图片轮播、各种小的动画、延时操作等等;定时器函数只有两个setTimeout、setInterval,这两个工作原理相同,唯一的区别是:setTimeout只执行一次,setInterval循环执行;通过以下实例看看对定时器原理掌握程度:

  定时器3个实例

    首先声明这三个实例输出皆不同,先思考输出结果,以及为何不同

    实例一:

console.log(‘test1‘)
for(var i=0;i<10;i++){
    setTimeout(()=>{console.log(i)},1000);
}
console.log(‘test2‘)

    实例二:

console.log(‘test1‘)for(let i=0;i<10;i++){
    setTimeout(()=>{console.log(i)},1000);
}
console.log(‘test2‘)

    实例三

console.log(‘test1‘)
for(let i=0;i<10;i++){
    setTimeout(()=>{console.log(i)},1000*i);
}
console.log(‘test2‘)

    结果如下:

      实例一:‘test1‘ --> ‘test2‘ -->  同时输出十个10

      实例二:‘test1‘ --> ‘test2‘ -->  同时输出0-9数字

      实例三:‘test1‘ --> ‘test2‘ --> 每哥1s输出一个数字,数字从0-9

    至于原因等会再讲,首先要先明白定时器的工作原理,而定时器的原理正是javascript事件循环模型的体现;

javascript运行机制:Event Loop

  必须明确一点:javascript是单线程,同一时间只能做一件事;

  单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。

  所谓单线程,是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个。不妨叫它主线程。但是实际上还存在其他的线程。例如:处理AJAX请求的线程、处理DOM事件的线程、定时器线程、读写文件的线程(例如在Node.js中)等等。这些线程可能存在于JS引擎之内,也可能存在于JS引擎之外,在此我们不做区分。不妨叫它们工作线程

  如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多时候CPU是闲着的,因为IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行。

  JavaScript语言的设计者意识到,这时主线程完全可以不管IO设备,挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。于是,所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

  具体来说,异步执行的运行机制如下(以ajax为例):

             

解答上述实例

参考:(优质的文档能够准确,快速地理解掌握知识点;感谢以下文档)

[1] javascript: 彻底理解同步、异步、事件循环(Event Loop)
[2] javascript 运行机制详解:在谈Event Loop

时间: 2024-10-10 22:06:07

定时器运行原理 && javascript事件循环模型的相关文章

转向Javascript系列之从setTimeout说事件循环模型

本文首发在alloyteam团队博客,链接地址http://www.alloyteam.com/2015/10/turning-to-javascript-series-from-settimeout-said-the-event-loop-model/ 作为一个从其他编程语言(C#/Java)转到Javascript的开发人员,在学习Javascript过程中,setTimeout()运行原理是我遇到的一个不太好理解的部分,本文尝试结合其他编程语言的实现,从setTimeout说事件循环模型

js: 从setTimeout说事件循环模型

一.从setTimeout说起 setTimeout()方法不是ecmascript规范定义的内容,而是属于BOM提供的功能.查看w3school对setTimeout()方法的定义,setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. 语法setTimeout(fn,millisec),其中fn表示要执行的代码,可以是一个包含javascript代码的字符串,也可以是一个函数.第二个参数millisec是以毫秒表示的时间,表示fn需推迟多长时间执行. 调用setTimeou

【转】从settimeout说事件循环模型

原文地址:http://www.alloyteam.com/2015/10/turning-to-javascript-series-from-settimeout-said-the-event-loop-model/#prettyPhoto 作为一个从其他编程语言(C#/Java)转到Javascript的开发人员,在学习Javascript过程中,setTimeout()方法的运行原理是我遇到的一个不太好理解的部分,本文尝试结合其他编程语言的实现,从setTimeout说事件循环模型 1.从

异步 JavaScript - 事件循环

简评:如果你对 JavaScript 异步的原理感兴趣,这里有一篇不错的介绍. JavaScript 同步代码是如果工作的 在介绍 JavaScript 异步执行之前先来了解一下, JavaScript 同步代码是如何执行的. 这里有两个概念需要了解: ** 执行上下文(Excution Context)** 执行上下文是一个抽象的概念,用于表示 JavaScript 的运行环境,任何代码都会有一个执行上下文. 全局代码运行在全局执行上下文,函数里的代码运行在函数执行上下文,每一个函数都有自己的

深入理解JavaScript事件循环机制

前言 众所周知,JavaScript 是一门单线程语言,虽然在 html5 中提出了 Web-Worker ,但这并未改变 JavaScript 是单线程这一核心.可看HTML规范中的这段话: To coordinate events, user interaction, scripts, rendering, networking, and so forth, user agents must use event loops as described in this section. Ther

深入理解 JavaScript 事件循环(一)— event loop

引言 相信所有学过 JavaScript 都知道它是一门单线程的语言,这也就意味着 JS 无法进行多线程编程,但是 JS 当中却有着无处不在的异步概念 .在初期许多人会把异步理解成类似多线程的编程模式,其实他们中有着很大的差别,要完全理解异步,就需要了解 JS 的运行核心——事件循环(event loop).在之前我对事件循环的认识也是一知半解的,直到我看了 Philip Roberts 的演讲 What the heck is the event loop anyway?,我才对事件循环有了一

浏览器中的JavaScript事件循环机制

浏览器的事件循环机制是HTML中定义的规范. JavaScript有一个主线程和调用栈,所有的任务都会被放到调用栈等待主线程执行. JS调用栈 是一种先进后出的数据结构.当函数被调用时,会被添加到栈中的顶部,执行完成之后就从栈的顶部移除该函数,直到栈内被清空. 同步任务.异步任务 JS单线程任务分为同步任务和异步任务.同步任务会在调用栈中按照顺序排队等待主线程执行,异步任务则会在异步有了结果之后将注册的回调函数添加到任务队列(消息队列)中等待主线程空闲的时候,也就是栈内被清空的时候,被读取到栈中

JS JavaScript事件循环机制

区分进程和线程 进程是cpu资源分配的最小单位(系统会给它分配内存) 不同的进程之间是可以同学的,如管道.FIFO(命名管道).消息队列 一个进程里有单个或多个线程 浏览器是多进程的,因为系统给它的进程分配了资源(cpu.内存)(打开Chrome会有一个主进程,每打开一个Tab页就有一个独立的进程) 浏览器的渲染进程是多线程的 1.GUI渲染线程 2.JS引擎线程 3.事件触发线程 4.定时触发器线程 5.异步HTTP请求线程 事件循环机制 上图解释: 同步和异步任务分别进入不同的执行"场所&q

深入理解JavaScript的事件循环(Event Loop)

一.什么是事件循环 JS的代码执行是基于一种事件循环的机制,之所以称作事件循环,MDN给出的解释为 因为它经常被用于类似如下的方式来实现 while (queue.waitForMessage()) { queue.processNextMessage(); } 如果当前没有任何消息queue.waitForMessage 会等待同步消息到达 我们可以把它当成一种程序结构的模型,处理的方案.更详细的描述可以查看 这篇文章 而JS的运行环境主要有两个:浏览器.Node. 在两个环境下的Event