北京景网站建设nba西部最新排名
宏任务和微任务
- JS为微任务和宏任务简单介绍
- 任务执行顺序例子
- 任务执行顺序简单例子
- 关于new Promise实例化过程的例子
JS为微任务和宏任务简单介绍
- js是单线程的,但是分同步异步
- 微任务和宏任务皆为异步任务,它们都属于一个队列
- 宏任务一般是:script、setTimeout、setInterval、postMessage
- 微任务:Promise.then ES6
- 先执行同步再执行异步,异步遇到微任务,先执行微任务,执行完后如果没有微任务,就执行下一个宏任务,如果有微任务,就按顺序一个一个执行微任务
任务执行顺序
同步任务 ——> 异步任务中微任务 ——> 异步任务中宏任务
任务执行顺序例子
function doFoo(fn) {this.code = 404;fn();
}function f() {setTimeout(() => {console.log(">>>" + this); // >>>[object window],语句3this.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在实例化的过程中所执行的代码都是同步进行的
关于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
分析
- 先同步再异步,从上往下编译执行,首先遇到同步任务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同理);