美文网首页
事件循环机制event loop - 同步线程 异步线程

事件循环机制event loop - 同步线程 异步线程

作者: JX灬君 | 来源:发表于2021-07-16 00:45 被阅读0次

EventLoop(事件循环)处理线程

关键词:Call Stack(调用栈),Task Queue(任务队列),线程(定时器触发线程,http异步线程)

let timeOutBack = function () {
      console.log("timeOut回调");
    }
    let httpBack = function () {
      console.log("http回调");
    }
    // 同步任务1
    console.log("同步任务1");
    // 异步定时任务1
    setTimeout(timeOutBack, 1000);
    // 异步http请求任务1
    ajax.get('/info',httpBack)
    // 同步任务2
    console.log("同步任务2");
上述代码执行时,在内存中的处理流程分别是:

1.执行到同步任务1时,直接将同步任务丢到调用栈(Call Stack),执行完毕后丢弃。

2.执行到异步定时任务1时,不会立即执行调用栈,而是放到任务队列(Task Queue)里,但是不是立即放入任务队列,而是放到对应的定时器触发线程里进行托管。

  1. 执行到异步http请求任务1时,更异步定时任务1一样,不同的是放到对应的http异步线程里进行托管。

4.执行到同步任务2时,跟同步任务1一样,直接将同步任务丢到调用栈里,执行完毕后丢弃。

5.同步任务2执行完后,调用栈(Call Stack空了),事件循环(Event Loop)一直在轮询任务队列(Task Queue),但此时定时器触发线程依然在定时器触发线程中托管,任务队列依然是空的。1秒后,定时器触发线程里托管的异步定时任务1被放到任务队列里。大概一毫秒的时间,异步定时任务1被事件循环机制捕获到,丢入调用栈(Call Stack),执行完毕后丢弃。

6.第2秒后,http异步线程里托管的异步http请求任务1被放到任务队列里,大概一毫秒的时间,异步http请求任务1被事件循环机制捕获到,丢入调用栈(Call Stack),执行完毕后丢弃。

所以整个代码执行输出的结果为:同步任务1,同步任务2,timeOut回调,http回调。

1. 同步和异步机制

  • 案例1
setTimeout(() => {
      console.log(1);
    }, 20);
    console.log(2);

    setTimeout(() => {
      console.log(3);
    }, 10); // 如果将10设为0,那么实际为4ms,定时器最低4ms
    console.log(4);
    console.time("AA");
    for (let i =0; i< 90000000; i++) {   // AA 47ms左右
      // do 
    }
    console.timeEnd("AA")
    console.log(5);
    setTimeout(() => {
      console.log(6);
    }, 20);
    console.log(7);
    setTimeout(() => {
      console.log(8);
    }, 10);

输出结果为:2 4 AA 5 7 3 1 8 6
先同后异原则:
js会开辟一个主线程,所有的同步代码先执行,其它异步代码会放到对应的异步线程里进行托管,然后通过事件循环机制,将托管之后放到任务队列里的代码轮询后执行。
假设同步执行事件为0ms。
执行顺序如下,同步任务2,4执行完,47毫秒后执行同步任务5,7.同步代码结束。事件循环机制启动轮询,10ms放入宏任务-异步任务3,20ms放入宏任务-异步任务1(因为已经过了47ms,所以马上输出3,1)47+10ms后放入宏任务-异步任务8,47+20ms后放入宏任务-异步任务6.
所以最后输出结果: 2 4 AA 5 7 3 1 8 6

2. Promise

  • 案例2
const button = document.getElementById("button")
    button.addEventListener("click", () => {
      Promise.resolve().then(() => console.log("Microtask 1"))
      console.log("Listener 1");
    })
    button.addEventListener("click", () => {
      Promise.resolve().then(() => console.log("Microtask 2"))
      console.log("Listener 2");
    })

页面点击 button结果为:Listener 1 Microtask 1 Listener 2 Microtask 2
js触发button.click()结果为:Listener 1 Listener 2 Microtask 1 Microtask

相关文章

网友评论

      本文标题:事件循环机制event loop - 同步线程 异步线程

      本文链接:https://www.haomeiwen.com/subject/pxompltx.html