千家信息网

JS运行机制实例分析

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,本篇内容主要讲解"JS运行机制实例分析",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"JS运行机制实例分析"吧!1.为什么JS是单线程的?JS的单线程,与它
千家信息网最后更新 2025年01月19日JS运行机制实例分析

本篇内容主要讲解"JS运行机制实例分析",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"JS运行机制实例分析"吧!

1.为什么JS是单线程的?

JS的单线程,与它的用途有关。

作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。

比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准

但是浏览器是多线程的

2.事件循环机制中的两种任务

宏任务:整体代码,setTimeout,setInterval等

微任务:new Promise ().then的回调,MutationObserver(前端回溯)用来监听事件的改变的

3.为什么要引入微任务的概念,只有宏任务不行吗

宏任务遵循先进先出的原则执行,但是如果在宏任务执行的过程中有了优先级更高的任务需要先执行,那么此时往任务队列中添加新任务的话,因为宏任务秉持着先进先出的原则,新添加的任务也只能是被排在后面的,那是万万不行的,所以才引入了微任务

4.事件循环

先执行同步,再执行异步,异步中先执行微任务再执行宏任务

首先,整体的js代码(作为第一个宏任务)开始执行的时候,会把所有代码分为同步任务、异步任务两部分,

同步任务会直接进入主线程依次执行,同步任务执行完后,执行异步任务,

异步任务会再分为宏任务和微任务,

微任务中先执行同步任务,异步任务依旧放到任务队列中排队,

当主线程空闲的时候,任务队列中异步任务再依次执行

上述过程会不断重复,这就是Event Loop,比较完整的事件循环

5.Promise

new Promise(() => {}).then()

敲黑板划重点——

前面的 new Promise() 这一部分是一个构造函数,这是一个同步任务

后面的 .then() 才是一个异步微任务

new Promise((resolve) => {

console.log(1)

resolve()

}).then(()=>{

console.log(2)

})

console.log(3)

//上面代码输出1 3 2

6.async / await

async/await本质上还是基于Promise的一些封装,而Promise是属于微任务的一种

所以在使用await关键字与Promise.then效果类似

setTimeout(() => console.log(4))

async function test() {

console.log(1)

await Promise.resolve()

console.log(3)

}

test()

console.log(2)

//上述代码输出1 2 3 4

setTimeout(() => console.log(4))

async function test() {

console.log(1)

await async2()

console.log(3)

}

function async2() {

console.log(5);

}

test()

console.log(2)

//上述代码输出1 5 2 3 4

await 修饰的函数及以前的代码,相当于与 new Promise 的同步代码

await 以后的代码相当于 Promise.then的异步

7.附上几道面试题

function test() {

console.log(1)

setTimeout(function () {

console.log(2)

}, 1000)

}

test();

setTimeout(function () {

console.log(3)

})

new Promise(function (resolve) {

console.log(4)

setTimeout(function () {

console.log(5)

}, 100)

resolve()

}).then(function () {

setTimeout(function () {

console.log(6)

}, 0)

console.log(7)

})

console.log(8)

//上述代码输出 1、4、8、7、3、6、5、2

async function async1() {

console.log('async1 start');

await async2();

console.log('async1 end');

}

async function async2() {

console.log('async2');

}

console.log('script start');

setTimeout(() => {

console.log('setTimeout');

}, 0);

async1();

new Promise((resolve)=> {

console.log('promise1');

resolve()

}).then(()=> {

console.log('promise2');

})

console.log('script end');

//上述代码输出

// 'script start'

//'async1 start'

//'async2'

//'promise1'

//'script end'

//'async1 end'

//'promise2'

//'setTimeout'

//await async2();

//相当于 new Promise((resolve) => {

async2();

resolve();

}).then(() => { console.log('async1 end') })

console.log('start');

setTimeout(() => {

console.log('children2');

Promise.resolve().then(() => {

console.log('children3');

})

}, 0);

new Promise((resolve, reject) => {

console.log('children4');

setTimeout(() => {

console.log('children5');

resolve('children6')

}, 0);

}).then(res => {

console.log('children7');

setTimeout(() => {

console.log(res);

}, 0);

})

// 上述代码输出

//'start'

//'children4'

//第一轮宏任务结束,发现没有微任务,原因:new Promise里并没有resolve(),只有resolve()才会把.then放到微任务里

//'children2'

//'children3'

//'children5'

//'children7'

//'children6'

const p = function () {

return new Promise((resolve, reject) => {

const p1 = new Promise((resolve, reject) => {

setTimeout(() => {

resolve(1)

}, 0);

resolve(2)

})

p1.then(res => {

console.log(res);

})

console.log(3);

resolve(4)

})

}

p().then(res => {

console.log(res);

})

console.log('end');

// 上述代码输出

//3

//end

//Promise的状态是唯一且不可改变的,所有当resolve(2)的时候.then已经被输出了,setTimeout里的resolve(1)就没有了

//2

//4

到此,相信大家对"JS运行机制实例分析"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0