1.对比同步和异步
使用异步的场景:
- 定时任务:setTimeout、setInterval
- 网络请求:ajax请求、动态<img>加载
- 事件绑定
//同步
console.log(100);
alert(200);//同步会造成阻塞
console.log(300);
//异步
console.log(100);
setTimeout(function(){
console.log(200);
},1000);
console.log(300);
//<img>加载示例
console.log('start');
var img = document.createElement('img');
img.onload = function(){
console.log('loaded');
}
img.src = '/xxx.png';
console.log('end');
2.同步任务和异步任务的优先顺序
JS是单线程的,即在同一时间只能做一件事。从上到下执行。
任务队列:分同步任务、异步任务(setTimeout()、setInterval(),异步任务要挂起,同步任务全部执行完再执行异步任务)。
Event Loop:同步任务放在运行栈里边全部执行,遇到异步任务先挂起,等到时间到了的时候(即使是0,浏览器最小的是4毫秒),Timer模块会把他放到异步队列中,当js引擎发现运行栈里边的同步任务全部执行完后,再去读异步任务队列,发现里边有东西后,读出来放到运行栈中执行,此时setTimeout函数体就变成了运行栈中的同步任务,执行完后,栈空了,再去监听异步队列中有没有,如果有,再去执行。这个循环过程就叫做event loop。
- 1.执行栈执行的是同步任务。
- 2.什么时候向异步队列中 取 任务。
- 3.什么时候往异步队列中 放 任务。
什么时候开启异步任务?
- setTimeout和setInterval;
- DOM事件(js的addEventListener,先注册函数体,触发时放入异步任务队列,再执行;eg:点击某一按钮浏览器卡死);
- es6中的Promise。
// 1.打印出顺序为1、3、2
console.log(1);
setTimeout(function(){//setTimeout异步任务要挂起,同步任务全部执行完再执行异步任务
console.log(2);
},0);//4毫秒延迟
console.log(3);
// 2.只输出a,while(true)是同步任务,一直在执行
console.log("a");
while(true){
}
console.log("b");
// 3.只输出A,同步任务全部执行完再执行异步任务
console.log("A");
setTimeout(function(){
console.log("B");
},0);
while(1){
}
3.异步任务(队列)的放入时间和执行时间
// 输出四个4,for循环是个同步任务
for(var i=0;i<4;i++){
setTimeout(function(){//到1s时,Timer模块才将其放入异步任务队列中(放入时间),等待事件循环执行(执行时间)
console.log(i);
},1000);
}
4.一道面试题
//1.setTimeout()异步任务
for(var i=0;i<5;i++){
setTimeout(function(){
console.log(new Date,i);
},1000);
}
console.log(new Date,i);
//运行结果
Thu Mar 15 2018 17:40:52 GMT+0800 (中国标准时间) 5
Thu Mar 15 2018 17:40:53 GMT+0800 (中国标准时间) 5
Thu Mar 15 2018 17:40:53 GMT+0800 (中国标准时间) 5
Thu Mar 15 2018 17:40:53 GMT+0800 (中国标准时间) 5
Thu Mar 15 2018 17:40:53 GMT+0800 (中国标准时间) 5
Thu Mar 15 2018 17:40:53 GMT+0800 (中国标准时间) 5
//2.立即执行函数
for(var i=0;i<5;i++){
(function(j=i){
setTimeout(function(){
console.log(new Date,j);
},1000);//此处为1000
})(i);
}
console.log(new Date,i);
//运行结果
Thu Mar 15 2018 17:46:53 GMT+0800 (中国标准时间) 5
Thu Mar 15 2018 17:46:54 GMT+0800 (中国标准时间) 0
Thu Mar 15 2018 17:46:54 GMT+0800 (中国标准时间) 1
Thu Mar 15 2018 17:46:54 GMT+0800 (中国标准时间) 2
Thu Mar 15 2018 17:46:54 GMT+0800 (中国标准时间) 3
Thu Mar 15 2018 17:46:54 GMT+0800 (中国标准时间) 4
//3.默认4毫秒延迟
for(var i=0;i<5;i++){
(function(j=i){
setTimeout(function(){
console.log(new Date,j);
},0);//此处为0
})(i);
}
console.log(new Date,i);
//运行结果
Thu Mar 15 2018 17:46:54 GMT+0800 (中国标准时间) 5
Thu Mar 15 2018 17:46:54 GMT+0800 (中国标准时间) 0
Thu Mar 15 2018 17:46:54 GMT+0800 (中国标准时间) 1
Thu Mar 15 2018 17:46:54 GMT+0800 (中国标准时间) 2
Thu Mar 15 2018 17:46:54 GMT+0800 (中国标准时间) 3
Thu Mar 15 2018 17:46:54 GMT+0800 (中国标准时间) 4