javascript执行线程是一个单线程。js异步编程的概念模型图(注意,仅仅是概念模型图,根据不同的浏览器有更高效的实现)如下:
setTimeout代码示例分析:
假设有以下的代码:
function working(seconds) { seconds = seconds || 1; var start = new Date(); var end = new Date(); while(end-start < seconds * 1000) { end = new Date(); }} console.log(new Date()); setTimeout(function() { console.log(new Date); working(5); setTimeout(arguments.callee, 3*1000);}, 3*1000); setTimeout(function() { console.log(new Date); working(3);}, 1000);
假设当前时间是0,并忽略代码运行时耗费的时间,那么程序运行后,会打印什么?
结合原理图,分析过程如下:(我们将第一个setTimeout中的匿名函数成为“任务1”,第二个setTimeout中的匿名函数成为“任务2”)
时间Javascript执行线程定时器线程任务队列
时间Javascript执行线程定时器线程任务队列
0打印当前时间,值为0 空
0第一次调用setTimeout函数:告知定时器线程3秒后将任务1推入任务队列3秒后推任务1空
0第二次调用setTimeout函数:告知定时器线程1秒后将任务2推入任务队列a. 3秒后推任务1b. 1秒后推任务2空
1 a. 2秒后推任务1b. 向队列推送任务2任务2
1从任务队列中获取到任务2,并开始执行任务2:1) 打印当前时间,值为12) 开始忙碌工作(working)2秒后推任务1空
2忙碌工作中1秒后推任务1空
3忙碌工作中向队列推送任务1任务1
4忙碌工作结束 任务1
4从任务队列中获取到任务1,开始执行任务1: 打印当前时间,值为4空
4~9开始忙碌工作(working),持续5秒
9调用setTimeout函数:告知定时器线程3秒后将任务1推入任务队列3秒后推任务1空
12 向队列推送任务1任务1
12从任务队列中获取到任务1,开始执行任务1:打印当前时间,值为12开始忙碌工作(working)空
12~17忙碌工作(working)持续5秒
...... 如此持续下去,每隔8秒打印一次当前时间......