• 事件循环


    本文记录对事件循环的理解

    setTimeout与setInterval

    • 定时器不是javascript自身的一个功能,是javascript运行在浏览器环境中浏览器为其实现的一个功能。
    • javascript是单线程的,同一时间只能执行一个代码块,这些代码块阻塞了异步事件的执行。当一个异步事件发生时(鼠标点击,定时器,ajax等),它就会排队,等线程空闲时才能执行。
    • 异步队列中的处理程序会有优先级,鼠标点击处理程序优先级会高于Timer处理程序与Interval处理程序。
      举例:
      一个javascript程序包括主程序代码,setTimeout,setInterval时,执行到setInterval时,会进入到队列中排队处理程序。队列中的setInterval处理程序在设定的时间内要执行但此时主程序代码块还没执行结束,则此次处理程序不能被执行。在下一次setInterval处理程序要执行时主程序还是没有执行结束,因为队列中已有setInterval处理程序,则不在向队列中推入setInterval处理程序,即此次作废。而setTimeout处理程序、鼠标点击处理程序则在异步队列中等主程序执行结束之后执行(setTnterval处理事件也是)。队列中事件处理程序的先后顺序由浏览器算法决定。

    不同点:

    1
    2
    3
    4
    5
    6
    7
    setTimeout(function() {
    setTimeout(repeatMe, 10);
    }, 10);

    setInterval(function() {

    }, 10)

    setTimeout要在前一个callback回调执行结束并延迟10ms以后,才能再次执行setTimeout(),
    而setInterval()则是每隔10ms就尝试执行callback回调,而不关注上一个callback是何时执行的。

    任务队列macrotask与microtask

    事件循环中的任务队列主要包括macrotask与microtask,执行的顺序为:

    1. 在 macrotask 队列中执行最早的那个 task ,然后移出
    2. 执行 microtask 队列中所有可用的任务,然后移出
    3. 下一个循环,执行下一个 macrotask 中的任务 (再跳到第2步)

    macrotask主要有setInterval与setTimeout,miscrotask主要有Promise.then()的回调。mascrotask产生的microtask可以在本次循环执行,而macrotask则需要下次循环执行。

    示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    大专栏  事件循环lass="line">27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    console.log('start')

    const interval = setInterval(() => {
    console.log('setInterval')
    }, 0)

    setTimeout(() => {
    console.log('setTimeout 1')
    Promise.resolve()
    .then(() => {
    console.log('promise 3')
    })
    .then(() => {
    console.log('promise 4')
    })
    .then(() => {
    setTimeout(() => {
    console.log('setTimeout 2')
    Promise.resolve()
    .then(() => {
    console.log('promise 5')
    })
    .then(() => {
    console.log('promise 6')
    })
    .then(() => {
    clearInterval(interval)
    })
    }, 0)
    })
    }, 0)

    Promise.resolve()
    .then(() => {
    console.log('promise 1')
    })
    .then(() => {
    console.log('promise 2')
    })

    以上代码的输出结果?
    首次执行setTimeout、setTimeout,作为一个macrotask,将其回调函数放入自己的队列之中。在下一次循环中执行回调
    其次会执行microtask。
    重复以上步骤,输出:
    promise 1
    promise 2
    setInterval
    setTimeout 1
    promise 3
    promise 4
    setInterval
    setTimeout 2
    promise 5
    promise 6

  • 相关阅读:
    ngnix之笔记
    nginx之"/"结尾
    nginx之root和alias区别
    Python3 操作Excel--openpyxl
    python学习笔记之线程、进程和协程(第八天)
    python之堡垒机(第九天)
    python学习笔记之socket(第七天)
    python学习笔记之paramiko和sqlalchemy (第九天)
    python之在线PK游戏(第六天)
    python学习笔记之类class(第六天)
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12261121.html
Copyright © 2020-2023  润新知