JS性能优化——setTimeout学习笔记

在最近接触到的代码中,遇到了一个在

angularJs中使用setTimeout的问题。就是在setTimeout中对scope中的属性进行修改,修改后的值不会立即更新到视图上。

setTimeout()主要用于推迟指定时间后处理相应的函数。在说setTimeout()之前,先要了解JS的线程。

我以前只知道JS运行是“”单线程”的,但对线程这东西一直没概念(还为单线程怎么还有异步方法这个问题揪心过)。最近查了一下,才总算明白了点。

精彩内容

首先,单线程的是指js只能在一个线程上运行,也就说,js在一个时间里只能执行一个js任务。js是单线程的,js引擎线程是有多个,一个主线程,其它的后台配合主线程。其中,js引擎里面有一个消息队列,里面放着各种需要当前程序处理的消息。

Js要执行的任务主要分为同步任务和异步任务。其中,同步任务会放在主线程中排队执行,而异步任务会放入消息队列排队,不会放到主线程中。

JS的运行过程大致如下:

(1)同步任务都放到主线程上执行,浏览器会按顺序处理主线程中的任务。

(2)主线程之外,还存在一个“任务队列”。只要异步任务有了运行结果,就在“任务队列”之中放置一个事件。

(3)一旦“执行栈”中的所有同步任务执行完毕,系统就会读取“任务队列”,看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。

(4)主线程不断重复上面的第三步。

Js的事件循环(Event Loop)大概就是指主线程执行完当前任务后读取任务列表的循环过程。

回到setTimeout()上,这个和异步任务的执行时一样的。当过了指定时间之后,所设定的函数就会加入消息队列中,若当前无其他任务执行,则这个函数就得到执行机会;否则,要先等主线程上的同步任务和在消息队列中排前面的任务执行完毕,它才能够得到执行机会。而这个要被执行的函数会被全局对象调用。这就是我一开始遇到的问题的原因,被执行的函数会被全局对象调用,于是AngularJs无法做出及时的更新,需要在里面添加$apply来进行手动更新。

对于setTimeout的使用,网上的经典例子如下:

因为setTimeout()是异步的,所以上面会进入死循环。

另外,如果setTimeou()里面传递字符串作为执行参数,例如:

此时,他将会调用eval()去执行这段代码,里面的字符串代码将会在全局环境下执行,上面setTimeout()执行的将会是全局的a()函数,而不是b()里面的a()。

下期预告:性能优化-图片懒加载

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180205G0V5MD00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励