本文是学习js定时器、单线程、同步异步任务的笔记,只适合初学者。javascript
JavaScript提供定时执行代码的功能,该功能主要由setTimeout()和setInterval()这两个函数来实现html
setTimeout函数用来指定某个函数或某段代码,在多少毫秒以后执行。
第一个参数是函数名或者语句,第二个参数延迟的时间参数,单位为msjava
var timerId = setTimeout(function|code, delay) setTimeout('console.log(2)',1000);
它返回定时器的编号,之后能够用来取消这个定时器。ajax
推迟执行的代码必须以字符串的形式,放入setTimeout。
由于引擎内部使用eval函数,将字符串转为代码。
若是推迟执行的是函数,则能够直接将函数名,放入setTimeout。
一方面eval函数有安全顾虑,另外一方面为了便于JavaScript引擎优化代码,setTimeout方法通常老是采用函数名的形式安全
setInterval函数的用法与setTimeout彻底一致,区别仅仅在于setInterval指定某个任务每隔一段时间就执行一次。若是不取消的话,就会无限次的定时执行。
第一个参数是函数名或者语句,第二个参数是间隔执行的时间,单位为ms
例一:实现自增数据输出服务器
var i=0 var timer=setInterval(function(){console.log(i++)},1000) //不要在function传递i参数,否则获得的就是NaN
例二:实现定时器的功能闭包
var timer=setInterval(function(){console.log(new Date)},1000)
setTimeout和setInterval函数,都返回一个表示计数器编号的整数值。
将该整数传入clearTimeout和clearInterval函数,就能够取消对应的定时器。异步
var id1 = setTimeout(f,1000); var id2 = setInterval(f,1000); clearTimeout(id1); clearInterval(id2);
五:举个例子
其实这篇文章写定时器的经典案例写的很棒JavaScrip同步、异步、回调执行顺序之经典闭包setTimeout分析async
var i=0; for(var i=0; i<10; i++){ setTimeout(function(){ console.log(i) }, 1000) }
执行结果:函数
解析:先执行主线程的for循环,for循环执行了10次,把匿名函数添加了到任务序列10次。等for循环执行完毕,i变成10以后,把任务序列的函数添加到主线程,输出10次i=10.
var t = true; setTimeout(function(){ t = false; }, 1000); while(t){console.log('end') }
执行结果:不停的输出end,不会再1000ms以后中止的。
解析:由于while循环是在主线程执行,主线程的while的循环不中止,是不会再执行任务队列里面setimeout的函数的。
5、6、七章的内容所有来源于 阮一峰JavaScript 标准参考教程(alpha)
单线程模型指的是,JavaScript 只在一个线程上运行。也就是说,JavaScript 同时只能执行一个任务,其余任务都必须在后面排队等待。
注意,JavaScript 只在一个线程上运行,不表明 JavaScript 引擎只有一个线程。事实上,JavaScript 引擎有多个线程,单个脚本只能在一个线程上运行(称为主线程),其余线程都是在后台配合。
5、6、七章的内容所有来源于 阮一峰JavaScript 标准参考教程(alpha)
程序里面全部的任务,能够分红两类:同步任务(synchronous)和异步任务(asynchronous)。
同步任务是那些没有被引擎挂起、在主线程上排队执行的任务。只有前一个任务执行完毕,才能执行后一个任务。
异步任务是那些被引擎放在一边,不进入主线程、而进入任务队列的任务。只有引擎认为某个异步任务能够执行了(好比 Ajax 操做从服务器获得告终果),该任务(采用回调函数的形式)才会进入主线程执行。
JavaScript 运行时,除了一个正在运行的主线程,引擎还提供一个任务队列(task queue),里面是各类须要当前程序处理的异步任务。
首先,主线程会去执行全部的同步任务。等到同步任务所有执行完,就会去看任务队列里面的异步任务。若是知足条件,那么异步任务就从新进入主线程开始执行,这时它就变成同步任务了。等到执行完,下一个异步任务再进入主线程开始执行。一旦任务队列清空,程序就结束执行。
引用这一次,完全弄懂 JavaScript 执行机制这篇文章的解析:
同步和异步任务分别进入不一样的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
当指定的事情完成时,Event Table会将这个函数移入Event Queue。
主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
上述过程会不断重复,也就是常说的Event Loop(事件循环)。
来源:若是没有callback函数,会先执行f2,f3函数再执行f2函数。
可是若是f1,f2函数是有前后顺序的,必须f1执行完成,再执行f2的话(f1多是获取ajax,f2是处理ajax数据),就须要回调函数。
给f1设置callback函数作参数,而后把这个参数当成函数执行,执行f1的过程当中,设置了一个定时器,等数据到来以后,再去执行callback函数。而后把f2做为f1的参数来调用
function f1(callback){ setTimeout(function(){ //作某件事,可能好久 console.log('别急,开始执行f1') for(var i=0;i< 100000;i++){ } console.log('f1执行完了') callback() }, 0); } function f2(){ console.log('执行f2'); } function f3(){ console.log('执行f3'); } f1(f2) //当f1执行完以后再执行 f2 f3()
转载一篇函数节流与函数防抖,写的很是好,具体内容可看这篇文章。我再也不赘述,我只记录一下节流的代码
var timer function hiFrequency(){ if(timer){ clearTimeout(timer) } timer = setTimeout(function(){ console.log('do something') }, 300) } hiFrequency() hiFrequency() hiFrequency()