本篇内容主要讲解“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运行机制实例分析”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。