JavaScript执行机制

JavaScript是单线程

同步与异步: 

 

JavaScript执行机制_第1张图片

 

 

 

 

  • macro-task(宏任务):包括整体代码script,setTimeout,setInterval
  • micro-task(微任务):Promise,process.nextTick

JavaScript执行机制_第2张图片

console.log('执行开始');
setTimeout(() => {
 console.log('timeout') 
}, 0);
new Promise(function(resolve) {
    console.log('进入')
    resolve();
}).then(res => console.log('Promise执行完毕') )

console.log('执行结束');

输出:

1.执行开始

2.进入

3.执行结束

4.Promise执行完毕

5.timeout

 

 

JavaScript执行机制_第3张图片

第一步(先分同步和异步):.整体代码开始执行,首先分为同步和异步,同步按顺序执行,Promise前半部分是同步,then里边的才是异步。

                                      同步                                                                 异步

1.console.log('执行开始');

2.new Promise(function(resolve) {

console.log('进入')

resolve();

})。(promise前半部分)

3.console.log('执行结束');

setTimeout()、Promise后边的then是异步

 

到这里,同步先进入主线程,依次执行完毕,开始处理异步。

上面分出来了同步和异步,同步部分相当于首个宏任务,异步部分需要按照宏任务和微任务的规则执行。上边说明了setTimeout是宏任务,Promise是微任务。

然后可以拆分成这样:

                                         宏任务                                                                                微任务

1.console.log('执行开始');

2.new Promise(function(resolve) {

console.log('进入')

resolve();

})。(promise前半部分)

3.console.log('执行结束');

4.then(res => console.log('Promise执行完毕') )     (Promise后边的then属于微任务)

setTimeout(() => {

console.log('timeout')

}, 0);

 

执行顺序:

JavaScript执行机制_第4张图片

宏任务和微任务相当两个队列(队列先进先出),

区分宏任务和微任务前先要区分同步和异步,同步部分作为首个宏任务压入队列。接下来从上到下从异步中区分宏任务和微任务。

 

 

捡值: 1.执行开始,2.进入 3.执行结束 4.Promise执行完毕 5.timeout

再来看一个复杂的:

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')
    })
})

先分同步的部分出来作为首个宏任务,遇到同级的微任务放在右边

                                               宏任务                                                                                       微任务

1. console.log('1');

2. new Promise(function(resolve) {

console.log('7');

resolve();

})

 

4. process.nextTick(function() {

console.log('6');

})

 

5. then(function() {

console.log('8')

})

setTimeout(function() {

console.log('2');

process.nextTick(function() {

console.log('3');

})

new Promise(function(resolve) {

console.log('4');

resolve();

}).then(function() {

console.log('5')

})

})

 

setTimeout(function() {

console.log('9');

process.nextTick(function() {

console.log('10');

})

new Promise(function(resolve) {

console.log('11');

resolve();

}).then(function() {

console.log('12')

})

})

 
   

 

第一步:

 

JavaScript执行机制_第5张图片

 

 

从左到右:第一个宏任务输出:1,7,第一个微任务输出6,8

第一行输出了:1,7,8

 

第二行:

发现setTimeout里边有宏任务和微任务,剖析第一个setTimeout

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

同步部分(宏任务):

console.log('2');
new Promise(function(resolve) {
        console.log('4');
        resolve();
    })

微任务:

  process.nextTick(function() {
        console.log('3');
    })
    then(function() {
        console.log('5')
    })
})

 

于是变成:

                                                      宏任务                                                                                 微任务

1. console.log('1');

2. new Promise(function(resolve) {

console.log('7');

resolve();

})

 

4. process.nextTick(function() {

console.log('6');

})

 

5. then(function() {

console.log('8')

})

6.console.log('2');

7.new Promise(function(resolve) {

console.log('4');

resolve();

})

8. process.nextTick(function() {

console.log('3');

})

9. then(function() {

console.log('5')

})

})

setTimeout(function() {

console.log('9');

process.nextTick(function() {

console.log('10');

})

new Promise(function(resolve) {

console.log('11');

resolve();

}).then(function() {

console.log('12')

})

})

 
   

执行顺序:

JavaScript执行机制_第6张图片

输出:1,7,6,8,2,4,3,5

 

剩下最后一个setTimeout,剖析:

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

 

同步部分(宏任务):

console.log('9');
new Promise(function(resolve) {
        console.log('11');
        resolve();
    })

微任务:

  process.nextTick(function() {
        console.log('10');
    })
    then(function() {
        console.log('12')
    })
})

于是变成:

                                      宏任务                                                                                           微任务

1. console.log('1');

2. new Promise(function(resolve) {

console.log('7');

resolve();

})

 

4. process.nextTick(function() {

console.log('6');

})

 

5. then(function() {

console.log('8')

})

6.console.log('2');

7.new Promise(function(resolve) {

console.log('4');

resolve();

})

8. process.nextTick(function() {

console.log('3');

})

9. then(function() {

console.log('5')

})

})

10.console.log('9');

11.new Promise(function(resolve) {

console.log('11');

resolve();

})

12.process.nextTick(function() {

console.log('10');

})

13.then(function() {

console.log('12')

})

})

   

 

执行顺序:

JavaScript执行机制_第7张图片

捡值:1,7,6,8,2,4,3,5,9,11,10,12

 

还有记住一点:从上往下区分。知道如何把代码分成同步异步、从上到下区分宏任务和微任务就知道代码的执行顺序啦!

 

注意:process.nextTick可能 会因为不同的nodejs版本而导致版本不同。

 

 

你可能感兴趣的:(JavaScript)