!定时器、线程进程、事件循环EventLoop(/回流重绘)、Promise

定时器

定时执行代码的功能。

运行机制:

setTimeout和setInterval的运行机制是,将指定的代码移出本次执行,等到下一轮Event Loop时,再检查是否到了指定时间。如果到了,就执行对应的代码;如果不到,就等到再下一轮Event Loop时重新判断。
setTimeout和setInterval都是把任务添加到“任务队列”的尾部。因此,它们实际上要等到当前脚本的所有同步任务执行完,然后再等到本次Event Loop的“任务队列”的所有任务执行完,才会开始执行。
4ms

settimeout();

var timerId = settimeout(function, delay毫秒, …args);
IE 9.0以下版本,只允许setTimeout有两个参数
定义:在delay毫秒后,执行一次function,并且可以传递一些参数给function。settimeout会返回一个id整数(表示定时器的编号),可以用来取消定时器。
清除clearTimeout(timerId1);
特点:它只执行一次。settimeout的延迟时间并不是准确的,它只是表示最早可能执行的时间。

setinterval();

var timerId2= setinterval(function, interval毫秒, …args);
定义:每隔interval毫秒,执行一次function,并且可以传递一些参数给function。setinterval也会返回一个id整数(表示定时器的编号),可以用来取消定时器。
清除clearInterval(timerId2);
特点:它会不断重复执行,直到被清除。setinterval的执行间隔并不是准确的,它也会受到其他代码的影响,比如浏览器的事件循环,或者其他的定时器。如果function的执行时间超过了interval,那么setinterval会累积一些未执行的任务,导致后续的执行时间不稳定,甚至出现堆积的情况。
例如,下面的代码会每隔1秒打印出一个数字,从1开始递增,但是如果function的执行时间超过了1秒,或者浏览器对setinterval进行了优化,那么打印出的数字可能会不连续,或者不按照预期的顺序。
在这里插入图片描述

区别:

settimeout只执行一次,而setinterval会不断重复执行,直到被清除。
settimeout和setinterval的延迟时间和执行间隔都不是准确的,它们会受到其他代码和浏览器的影响。
settimeout和setinterval的执行顺序也不是确定的,它们会受到浏览器的优化策略的影响。
Q1: 为什么我的setInterval函数在浏览器的非激活标签中运行得慢?
答: 大多数现代浏览器为了优化性能和减少电池消耗,当标签页不在前台或被最小化时,会自动减慢setInterval和setTimeout的执行频率。如果需要在非激活标签中保持正常的执行频率,可以考虑使用Web Workers,因为它们在后台线程中运行,不受此限制。
Q2: 是否可以同时使用setTimeout和setInterval?
答: 当然可以。setTimeout和setInterval可以根据需求同时使用。例如,你可能想使用setInterval进行轮询,而在某些特定情况下使用setTimeout进行单次的延迟操作。
Q3: setTimeout中设置的0毫秒的延迟意味着函数会立即执行吗?
答: 不一定。虽然setTimeout的延迟时间被设为0毫秒,但由于JavaScript的事件循环机制,它仅仅是将回调函数放入任务队列中,等待当前执行栈清空。如果当前执行栈中有其他任务,那么即使设置为0毫秒,回调函数的执行仍然会被推迟。

JS中的计时器能做到精确计时吗?为什么?

参考:

不行,因为:
1 .计算机硬件没有原子钟,无法做到精确计时。

2 .操作系统的计时函数本身就有少量偏差由于 JS 的计时器最终调用的是操作系统的函数,也就携带了这些偏差

3.按照 W3C 的标准,浏览器实现计时器时,如果嵌套层级超过 5 层,则会带有 4 毫秒的最少时间,这样在计时时间少于4毫秒时又带来了偏差

  1. 受事件循环的影响,计时器的回调函数只能在主线程空闲时运行,因此又带来了偏差

线程和进程

浏览器新开一个窗口?—>进程
进程是CPU资源分配的最小单位;线程是CPU调度的最小单位。
在这里插入图片描述

在这里插入图片描述
通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源,在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位,由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度。

js事件循环机制EventLoop

JS单线程实现复杂化 在这里插入图片描述

如何理解JS单线程,JS的异步

参考:
JS是一门单线程的语言,这是因为它运行在浏览器的渲染主线程中,而渲染主线程只有一个并且渲染主线程承担着诸多的工作,渲染页面、执行 JS ,解析htmlcss,执行事件回调等都在其中运行。如果使用同步的方式,就极有可能导致主线程产生阻塞,从而导致消息队列中的很多其他任务无法得到执行。这样一来,一方面会导致繁忙的主线程白白的消耗时间,另一方面导致页面无法及时更新,给用户造成卡死现象。

所以浏览器采用异步的方式来避免。具体做法是当某些任务发生时,比如计时器、网络、事件监听,主线程将任务交给其他线程去处理,自身立即结束任务的执行,转而执行后续代码。当其他线程完成时,将事先传递的回调函数包装成任务,加入到消息队列的末尾排队,等待主线程调度执行。在这种异步模式下,浏览器永不阻塞,从而最大限度的保证了单线程的流畅运行。

定义:
A.主线程循环不断的从任务队列中读取事件(任务),这整个过程就称为Event Loop(事件循环)。
/B. JavaScript 的事件循环是一种机制,用于处理异步任务,通过不断循环执行任务队列中的事件,确保非阻塞的单线程代码执行顺序。

  • 所有任务可以分成两种:

    同步任务(synchronous):在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务
    异步任务(asynchronous):不进入主线程、而进入任务队列(task queue)的任务,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

  • 异步执行的运行机制:(同步执行也是如此,因为它可以被视为没有异步任务的异步执行。)

    1. 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
    2. 主线程之外,还存在一个任务队列(task queue)。只要异步任务有了运行结果,就在任务队列之中放置一个事件。
    3. 一旦"执行栈"中的所有同步任务执行完毕,系统就会读取任务队列,看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行
    4. 主线程不断重复上面的第三步。

堆、执行栈、队列图:
在这里插入图片描述

执行流程

事件循环机制的核心就是观察者模式。程序执行的流程:

  1. js程序进入线程,函数入栈,当遇到同步代码的时候就顺序执行,遇到异步代码时,把异步任务抛给WebAPIs执行,然后继续执行接下来的同步代码,直到栈为空。
  2. 在步骤1进行的同时,WebAPIs执行异步任务,当执行完一个异步任务就将其对应的回调函数放入任务队列(Callback Queue)中等待。
    WebAPIs是由C++实现的浏览器创建的线程,处理诸如DOM事件,http请求,定时器等异步任务。
  3. 当执行栈为空时,从Callback Queue中取出队列头放入执行栈中,回到第一步。
    当执行完一个异步任务就将其对应的回调函数放入任务队列(Callback Queue)中。
    ?但我们是如何判断这个异步任务执行完了呢——观察者模式。任务队列是观察者,WebAPIs是被观察者,观察者要求被观察者当发生执行完异步任务这一事件时,通知他执行完了,并将该事件对应的回调函数传过来。

优缺点及与多线程的比较

js事件循环机制 优缺点与多线程的比较:
通过事件循环机制,我们就可以实现代码的异步,从而不会堵塞线程。
通过这一特性,
js在IO上有着卓越的表现,因为IO操作不再会堵塞住线程。
可以做到高并发。稍微解释一下为什么能够高并发——当同时有多个任务要执行,js将他一一排列起来,然后按顺序执行,这样cpu就不会因为同时要处理的工作太多而负载过大。


白银时代:多线程。黄金时代:事件驱动。不过我不敢说事件驱动就是比多线程好,但他确实没有多线程的这些恼人的缺陷。

如果有大量的线程,会影响性能,因为操作系统需要在线程之间不停进行上下文切换。
通常数据是多个线程共享的,需要上锁,同时又要防止出现死锁现象。
IO会堵塞住一个线程。
但同时的,js也有他的缺陷。
不适合cpu密集型。也解释一下——如一段代码需要非常大量的计算量,以至于他长时间地占着线程,这就堵塞了,后继的同步代码及异步代码都无法执行。不过,html5推出了web worker,可以有效地解决这一缺陷,在本章不表,后面我会专门写一篇文章来讲他。
只能使用一个线程,无法充分利用计算机的多核cpu。
可靠性低,一旦一个环节崩溃则整个程序全部崩溃。

比较浏览器与 Node 的事件循环

事件循环是计算机的一种运行机制,不同技术在具体实现和调度机制上有所不同。浏览器与 Node 的事件循环差异有:
宏任务与微任务的执行顺序
浏览器:执行 1 个宏任务 -> 处理所有的微

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值