咱们用反证法证实这个问题,假设js是多线程的。es6
场景描述:promise
假设如今有2个进程:process1,process2。因为是js是多进程的,因此这两个进程同时对一个dom进行操做。浏览器
process1 删除了该dom。bash
process2 编辑了该dom。多线程
同时下达2个矛盾的命令,浏览器究竟该如何执行呢?dom
显然做为浏览器脚本语言,就决定了js只能是单线程的,也称为主线程。异步
一样用反证法,假设js是同步的。oop
场景描述:ui
若是JS中不存在异步,只能自上而下执行,若是上一行解析时间很长,那么下面的代码就会被阻塞。spa
对于用户而言,阻塞就意味着"卡死",这样就致使了不好的用户体验。
经过的事件循环(event loop)实现异步。
涉及概念: 运行栈(同步任务)、任务队列(异步任务)、event loop
不断去任务队列中取异步任务的过程叫event loop
何时会开启异步任务:setTimeout 和 setIntveral、DOM事件、es6中的promise等
语句放入异步任务队列时机:遇到异步任务不会马上把代码放到任务队列中,会等到触发时(settimeout 时间到了 dom事件触发了)在放到任务队列中:
var a= 1;
setTimeout(a, 1000);
setTimeout(b, 500);
//b先被放到异步队列
复制代码
// 1 3 2
console.log(1); //同步任务
setTimeout(function(){ //异步任务
console.log(2);
},0)
console.log(3); //同步任务
复制代码
// 1
console.log(1); //同步任务
while(true){ //同步任务
}
console.log(2); //同步任务
复制代码
// 1
console.log(1); //同步任务
setTimeout(function(){ //异步任务
console.log(2);
},0)
while(true){ //同步任务
}
复制代码
//4 4 4 4
for(var i=0;i<4;i++){ //同步任务
setTimeout(function(){ //异步任务
console.log(i);
},1000)
}
复制代码
//2 4 3 1
setTimeout(function(){
console.log('1')
});
new Promise(function(resolve){
console.log('2');
resolve();
}).then(function(){
console.log('3')
});
console.log('4');
复制代码