浏览器只有一个线程才能有效的保证处理操作的准确性。
从实际上去说也就是V8引擎的一种机制,实际上是一个永动机机制,也就是一直不停的运行。
代码被分成两种任务形式,:一种是同步任务一种是异步任务
首先执行同步任务,同步任务有人说就是立即执行的任务,这个解释我认可。同步任务在主线程上按先后顺序执行,每个任务形成一个执行栈,每个任务有一个执行上下文,执行完后释放。
(1)主线程之外,还存在一个"任务队列"(task queue)。任务队列是用来处理异步任务的,异步任务大家都知道有定时器系列,Promise还有ajax还有各种点击事件。
(2)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。哪些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(3)主线程不断重复上面的第2步。
而事件队列event-loop是主线程对异步任务的处理机制。
有个问题:就是当嵌套发生时,现在都知道异步任务分为宏任务和微任务,并且微任务优先于宏任务执行。但是当微任务里面调用宏任务时候,主线程怎么处理呢?是根执行上下文有关吗。我也说不准,然后我找了一个例子测试。然后看到输出结果明白了。
new Promise(resolve => {new Promise(resolve => { console.log('promise1'); resolve(); }).then(function() { setTimeout(() => console.log('timeout2'), 10); console.log('then1') }) new Promise(resolve => { console.log('promise3'); resolve(); }).then(function() { setTimeout(() => console.log('timeout3'), 10); console.log('then3') }) setTimeout(function() { console.log('timeout1'); }, 10); console.log('script end'); console.log('promise1'); resolve(); }).then(function() { setTimeout(() => console.log('timeout2'), 10); console.log('then1') }) new Promise(resolve => { console.log('promise3'); resolve(); }).then(function() { setTimeout(() => console.log('timeout3'), 10); console.log('then3') }) setTimeout(function() { console.log('timeout1'); }, 10); console.log('script end');
总结:
1,主线程对最顶层上下文的任务做了任务区分,异步任务放到异步队列,同步任务直接执行。
2,如果在同步里面遇到了异步任务,那么按照位置先后关系放到异步队列里面,如果异步任务里面调用了异步任务,那么自然放在同步任务中异步队列后面,至于多个异步任务中调用的异步队列则是看上层的执行顺序。
3,当同步任务的执行顺序确定,异步队列中的微任务顺序确定,那么仅剩下的异步队列的宏任务也就确定了,总的执行顺序也就确定了。