JS为微任务和宏任务简单介绍
- js是单线程的,但是分同步异步
- 微任务和宏任务皆为异步任务,它们都属于一个队列
- 宏任务一般是:script、setTimeout、setInterval、postMessage
- 微任务:Promise.then ES6
- 先执行同步再执行异步,异步遇到微任务,先执行微任务,执行完后如果没有微任务,就执行下一个宏任务,如果有微任务,就按顺序一个一个执行微任务
任务执行顺序
同步任务 ——> 异步任务中微任务 ——> 异步任务中宏任务
任务执行顺序例子
function doFoo(fn) {
this.code = 404;
fn();
}
function f() {
setTimeout(() => {
console.log(">>>" + this); // >>>[object window],语句3
this.code = 401; // 语句4
}, 0)
console.log( this.code ); // 404,语句2
}
let obj = {
code: 200,
foo: f
};
var code = 500;
doFoo( obj.foo ); // 语句1
setTimeout(()=>{console.log(obj.code)}, 0); // 200,语句5
setTimeout(()=>{console.log(window.code)}, 0); // 401,语句6
分析
- 按照先同步再异步的顺序,从上往下编译执行,第一个执行doF( obj.foo )任务,将obj.foo作为参数传入到函数doFoo当中,此时作为调用者的对象还是window,doFoo函数中this.code = 404;将window对象下的code值修改为404
- 之后doFoo函数继续调用 f() 函数,f()函数中的setTimeout()是宏任务,先放入宏任务列表里,不执行,反而直接执行后面的 console.log( this.code ); 此时调用该函数的对象还是window,所以打印出404,继续接下来的任务,将两个setTimeout()都放入宏任务列表
- 执行第一个放入的setTimeout()任务,执行其中this.code=401,将window对象下的code的值又修改为401
- 执行第二个放入的setTimeout()任务,执行console.log(obj.code),整个过程中obj对象的code一直没被修改,所以还是200
- 执行第三个放入的setTimeout()任务,执行console.log(window.code),打印出401
任务执行顺序简单例子
console.log(1)
setTimeout(function() {
console.log(2)
}, 0)
const p = new Promise((resolve, reject) => {
resolve(4)
})
p.then(data => {
console.log(data)
})
console.log(3)
//1,3,4,2
分析
- 先同步再异步,从上往下编译执行,首先遇到同步任务console.log(1);输出1;
- 接着遇到setTimeout 异步宏任务,放入宏任务队列中;
- 接着遇到 Promise,new Promise在实例化的过程中所执行的代码都是同步进行的,但由于new Promise没有输出事件,所以无事发生。
- 接着遇到.then,then是异步微任务,不执行,加入到异步微任务列表;
- 遇到同步任务console.log(3);输出3;
- 主线程中同步任务执行完,从微任务队列中取出任务到主线程中,先取出作为微任务的.then,p.then 输出4,微任务执行完毕,微任务队列为空;
- 开始执行宏任务setTimeout 输出2,宏任务队列为空;
重点注意:new Promise在实例化的过程中所执行的代码都是同步进行的文章来源:https://www.toymoban.com/news/detail-612982.html
关于new Promise实例化过程的例子
console.log(1)
setTimeout(function() {
console.log(2)
new Promise(function(resolve) {
console.log(3)
resolve()
}).then(function() {
console.log(4)
})
})
new Promise(function(resolve) {
console.log(5)
resolve()
}).then(function() {
console.log(6)
})
setTimeout(function() {
console.log(7)
new Promise(function(resolve) {
console.log(8)
resolve()
}).then(function() {
console.log(9)
})
})
console.log(10)
//1,5,10,6,2,3,4,7,8,9
分析文章来源地址https://www.toymoban.com/news/detail-612982.html
- 先同步再异步,从上往下编译执行,首先遇到同步任务console.log(1);输出1;
- 遇到setTimeout 异步宏任务,放入宏任务队列中;
- 遇到 Promise,new Promise在实例化的过程中所执行的代码都是同步进行的,所以输出5,
- 所以接着遇到.then;.then,异步微任务,被分发到微任务Event Queue中;
- 遇到setTimeout,异步宏任务;放入宏任务队列中;
- 遇到同步任务console.log(10);输出10,主线程中同步任务全部执行完;
- 同步任务全部执行完,从微任务队列中取出任务到主线程中,输出6;
- 在从宏任务队列中取出任务到主线程中,执行第一个setTimeout,输出2,3,4(在宏任务中执行同步,同步,异步微任务);
- 在执行第二个setTimeout,输出7,8,9(和8同理);
到了这里,关于JavaScript的宏任务和微任务的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!