-
首先明白JS是单线程,单线程就是只能同时做一件事,要么吃饭要么说话,不能同时吃饭和说话,否则会噎住。
-
JS本身是从上往下一行一行的执行,但是setTimeout,setInterval,promise三个关键字会开启异步
-
一行一行执行为主线程
-
setTimeout,setInterval,promise进入异步队列等待
-
主线程执行完毕后异步队列进入主线程开始执行
-
主线程后一直执行,直到主线程空闲时,才会去异步队列中查看是否有可执行的异步任务,如果有就推入主进程中
console.log('打印' + 1);
setTimeout(function() {
console.log('打印' + 2);
})
new Promise(function(resolve, reject) {
console.log('打印' + 3);
}).then(
console.log('打印' + 4)
);;
console.log('打印' + 10);
new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('打印' + 5);
});
}).then(
console.log('打印' + 6)
);
setTimeout(function() {
new Promise(function(resolve, reject) {
console.log('打印' + 7);
});
})
// 结果为:1,3,4,10,6,2,5,7
setTimeout、setInterval和promise的执行顺序为promise->setTimeout/setInterval。
Promise定义之后便会立即执行,其后的.then()是异步里面的微任务。而setTimeout()是异步的宏任务。
主线程
js一直在做一个工作,就是从任务队列里提取任务,放到主线程里执行。
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
Event Loop
- 主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。