2020-02-16 javascript的执行机制

2020-02-16  本文已影响0人  FConfidence

javascript的执行机制

  1. 执行顺序探讨
setTimeout(function(){
  console.log('定时器开始啦')
});

new Promise(function(resolve){
    console.log('马上执行for循环啦');
    for(var i = 0; i < 10000; i++){
        i == 99 && resolve();
    }
}).then(function(){
    console.log('执行then函数啦')
});

console.log('代码执行结束');
  1. 关于javascript
  1. javascript的事件循环
  1. setTimeout
    • 不定时的setTimeout

      setTimeout(() => {
        task()
      },3000)
      
      sleep(10000000)
      
      /*
        却发现控制台执行task()需要的时间远远超过3秒,说好的延时三秒
      */
      
      • task()进入Event Table并注册,计时开始。
      • 执行sleep函数,很慢,非常慢,计时仍在继续。
      • 3秒到了,计时事件timeout完成,task()进入Event Queue,但是sleep也太慢了吧,还没执行完,只好等着。
      • sleep终于执行完了,task()终于从Event Queue进入了主线程执行。
    • setTimeout(fn, 0)会立即执行吗
      答案是不会的,setTimeout(fn,0) 的含义是,指定某个任务在主线程最早可得的空闲时间执行,意思就是不用再等多少秒了,只要主线程执行栈内的同步任务全部执行完成,栈为空就马上执行。

      关于setTimeout要补充的是,即便主线程为空,0毫秒实际上也是达不到的。根据HTML的标准,最低是4毫秒。有兴趣的同学可以自行了解。

  1. Promise & Process.nextTick

    • process.nextTick(callback)类似node.js版的"setTimeout",在事件循环的下一次循环中调用 callback 回调函数。
    • macro-task(宏任务):包括整体代码script,setTimeout,setInterval
    • micro-task(微任务):Promise,process.nextTick
    • 不同类型的任务会进入对应的Event Queue,比如setTimeout和setInterval会进入相同的Event Queue。

    时间循环的顺序: 决定js代码的执行顺序。
    进入整体代码(宏任务)后,开始第一次循环。接着执行所有的微任务。然后再次从宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务。

    setTimeout(function() {
        console.log('setTimeout');
    })
    
    new Promise(function(resolve) {
        console.log('promise');
    }).then(function() {
        console.log('then');
    })
    
    console.log('console');
    
    • 这段代码作为宏任务,进入主线程。
    • 先遇到setTimeout,那么将其回调函数注册后分发到宏任务Event Queue。(注册过程与上同,下文不再描述)
    • 接下来遇到了Promise,new Promise立即执行,then函数分发到微任务Event Queue。
    • 遇到console.log(),立即执行。
    • 好啦,整体代码script作为第一个宏任务执行结束,看看有哪些微任务?我们发现了then在微任务Event Queue里面,执行。
    • ok,第一轮事件循环结束了,我们开始第二轮循环,当然要从宏任务Event Queue开始。我们发现了宏任务Event Queue中setTimeout对应的回调函数,立即执行。
    • 结束。


      宏任务与微任务的关系
  1. 执行顺序分析
console.log('1');

setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})
process.nextTick(function() {
    console.log('6');
})
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})
上一篇 下一篇

猜你喜欢

热点阅读