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秒后执行了