JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?
1.JS 执行机制是单线程。
2.JS的Event loop(事件循环)是JS的执行机制,
我们先了解到JS任务的执行分类为:同步任务和异步任务。
按照这种的分类方式JS的执行机制是:
- 首先,判断JS是同步还是异步,同步进入主线程,异步进入Event table。
- 其次,异步任务在Event table中注册函数,当满足特定的条件,被推入Event queue。
- 最后,同步任务进入主线程后一直执行,直到主线程空闲后,才会去Event queue中查看是否有可执行的异步任务,如果有就推入主线程中执行。
循环以上三步执行,这就是Event loop。
以下代码的执行顺序:
setTimeout(()=>{
console.log("定时器开始执行");
})
new Promise(function(resolve){
console.log("准备执行for循环了");
for(var i=0;i<100;i++){
i==22&&resolve();
}
}).then(()=>console.log("执行then函数"));
console.log("代码执行完毕");
???
难道是异步任务执行的顺序不是前后顺序,而是另有规定?事实上,按照异步同步的划分并不准确。
而准确的方式应该是:
- macro-task(宏任务):包括整体代码script,setTimeout,setInterval
- micro-task(微任务):Promise,process.nextTic
先同步的,然后微任务,然后异步任务
setTimeout(function(){
console.log('执行了')
},3000)
我们一般说这段代码,在3秒后执行setTimeout内的函数。==>是否严谨???
但这种说法往往是不够严谨的,准确的解释是:3秒后,setTimeout函数会被推入Event queue(事件队列),而Event queue(事件队列)内的任务,只有在主线程空闲时才会执行。
所以,只有同时满足以下条件setTimeout内的函数才能被执行
1.3秒后
2.主线程空闲时
若主线程的执行任务很多,执行时间超过3秒,比如说5秒,那么setTimeout内的函数只能在5秒后执行了