推荐两篇优秀文章:
首先阅读 Javascript 异步实现机制
然后阅读 js-关于异步原理的理解和总结
这篇文章setTimeout与setInterval的坑以及优缺点也可以看看,但作者写的很乱,读起来有些困难。另外文中的例子也有问题,请看我文中例1的修正版。
要点总结:
- js代码中出现异步代码时(比如settimeout、ajax等),会交由宿主(浏览器或者nodejs的Libuv,它们是多线程的)执行,执行完后将任务加入到js的事件队列中。
- 当js的同步代码(也就是主线程)执行完后(也就是主线程空闲时),检查事件队列(这个过程叫事件循环,英文叫tick),若有要执行的任务,将其推入到js主线程中执行。
注意事项:
当使用setInterval()时,仅当没有该定时器的任何其他代码实例时,才将定时器代码添加到队列中,某些间隔会被跳过(抛弃)。
说人话就是,假如
setInterval(function(){
doSomething();
},1000);
我们会认为,它总是每隔1秒执行一次,但是:
如果已经有一个doSomething
加入到事件队列中了,还没等到它执行,1秒的时间就又到了,按理说会再次将一个doSomething
加入到事件队列,但是,事实上不会,会将这次忽略。
基于这个问题,所以请使用例1代替例2,请看下列代码:
//例一:
setTimeout(function(){
var args = arguments;
console.log("小马");
setTimeout(function(){args.callee();},1000);
},1000);
//例二:
setInterval(function(){console.log("小马");},1000);