Fork me on GitHub

《浏览器工作原理与实践》读书笔记(3)

浏览器中的页面循环系统

1.要想在线程运行过程中,能接收并执行新的任务,就需要采用事件循环机制。示例如下:

//GetInput
//等待用户从键盘输入一个数字,并返回该输入的数字
int GetInput(){
    int input_number = 0;
    cout<<"请输入一个数:";
    cin>>input_number;
    return input_number;
}

//主线程(Main Thread)
void MainThread(){
    for(;;){
        int first_num = GetInput();
        int second_num = GetInput();
        result_num = first_num + second_num;
        print("最终计算的值为:%d",result_num);
    }
}

2.为了能够接收其它线程(比如资源加载、交互事件、渲染事件、文件读写等)发送的消息,就在上面的事件循环机制上面加上消息队列。消息队列是一种数据结构,用来存放要执行的任务。

3.如何退出事件循环呢?很简单,加一个退出标记,每次事件循环的时候判断这个标记,如果有的话就退出循环。

4.为了保证任务的实时性(快速执行,不被消息队列中的任务延误)和效率(不影响当前正在执行的消息队列中的任务),我们把消息队列中的每个任务都加入一个微任务队列,而消息队列中的每个任务被称为宏任务。

5.其实除了有消息队列之外,chrome 还维护了一个延迟队列,用来存放 settimeout 的任务,执行完消息队列中的每个任务之后,就回去判断延迟队列中的任务该不该执行。(所以只有消息队列中的当前正在执行的任务会影响 settimeout 的延迟时间)

6.对于 settimeout 有以下几点需要注意:

1.如果 setTimeout 存在嵌套调用,那么系统会设置最短时间间隔为 4 毫秒
2.未激活的页面,setTimeout 执行最小间隔是 1000 毫秒
3.延时执行时间有最大值
4.使用 setTimeout 设置的回调函数中的 this 不符合直觉

7.使用 xhr 发送 http 请求的 demo:

function GetWebData(URL){
    /**
     * 1:新建XMLHttpRequest请求对象
     */
    let xhr = new XMLHttpRequest()

    /**
     * 2:注册相关事件回调处理函数
     */
    xhr.onreadystatechange = function () {
        switch(xhr.readyState){
          case 0: //请求未初始化
            console.log("请求未初始化")
            break;
          case 1://OPENED
            console.log("OPENED")
            break;
          case 2://HEADERS_RECEIVED
            console.log("HEADERS_RECEIVED")
            break;
          case 3://LOADING
            console.log("LOADING")
            break;
          case 4://DONE
            if(this.status == 200||this.status == 304){
                console.log(this.responseText);
                }
            console.log("DONE")
            break;
        }
    }

    xhr.ontimeout = function(e) { console.log('ontimeout') }
    xhr.onerror = function(e) { console.log('onerror') }

    /**
     * 3:打开请求
     */
    xhr.open('Get', URL, true);//创建一个Get请求,采用异步


    /**
     * 4:配置参数
     */
    xhr.timeout = 3000 //设置xhr请求的超时时间
    xhr.responseType = "text" //设置响应返回的数据格式
    xhr.setRequestHeader("X_TEST","time.geekbang")

    /**
     * 5:发送请求
     */
    xhr.send();
}

8.https 混合内容问题:当我们在 https 网站加载 http 的资源,都属于混合内容。如果这些内容不是 xhr 加载而是图片 src,视频 src等方式加载的话,浏览器会显示警告;但是如果这些内容是 xhr 加载的话,浏览器会阻挡这些请求

9.产生微任务一般有两种方式:使用 MutationObserver 监控某个DOM节点;使用 promise。

10.MutationObserver 使用异步 + 微任务的模式:使用异步解决了同步操作的性能问题;使用微任务解决了实时性的问题。

11.promise 主要是通过下面2点来解决嵌套回调问题的:1.回调函数的延时绑定。(先创建 promise 对象,然后使用executor执行业务逻辑,最后使用then来绑定回调函数)2.将回调函数的返回值穿透到最外层。

12.promise 的好处:1.消灭了嵌套回调。2.更好的信任度,回调函数只会执行一次。3.更好的流程处理。4.更好的错误处理。(可以通过监听 unhandledRejection 来捕获未处理的 promise 错误)

13.生成器是一个带星号的函数,而且是可以暂停执行和恢复执行的。执行生成器代码的函数叫做执行器。(参考著名的 co 框架)

14.协程是比线程更轻量级的存在,它完全受程序所控制,不被操作系统内核管理,也不会像线程切换那样消耗资源。

posted @ 2020-10-31 22:27  馒头加梨子  阅读(110)  评论(0编辑  收藏  举报