浏览器工作原理(一)

2020-07-28  本文已影响0人  js_lin

1.前言 浏览器做了什么?

浏览器做的工作就是将我们输入的url变成一张位图BitMap。
BitMap传给计算机的显卡驱动设备,就转换成我们可以人眼可见的光信号。


image.png

浏览器将url变成一张BitMap,本篇主要解释基础的渲染流程部分,真正的浏览器工作比这个要复杂得多。
具体步骤:

2. 前置知识:有限状态机

2.1 状态机是什么?

有限状态机,又叫状态机。

每个状态都是一个机器

在每个机器里,我们可以做计算、存储和输出......
所有的机器接受的输入是一致的
状态机的本身没有状态,用函数表示的话,就是纯函数。

每个状态机知道下一个状态

有两种状态机:
Moore状态机:每个机器都有确定的下一个状态。
Mealy状态机:每个机器根据输入决定下一个状态(大多数比较实用)。

2.2 Js中的有限状态机(Mealy型)

   // 每个函数是一个状态
   function state(input){  // 函数参数就是输入
        // 在函数中,可以自由的编写代码,处理每个状态的逻辑
        // 返回值作为下一个状态
        return next;
    }

   // 调用部分
   while(input){
       // 获取输入
       state = state(input);  //把状态机的返回值作为下一个状态
   }

看到这里,不明白不要紧,往下看例子就知道咯....

2.2.1 一般方法解决字符输入查找

例:问题1:在一个字符串中找到字符‘a’, 怎么解?
我们可以这样:

  function find(string){
     for(let c of string){
          if(c==='a')
              return true;
     }
     return false;
  }
    
  let result = find("i am a girl",'a');
  console.log(result); // true

例:问题2:在一个字符串中找到字符‘ab’, 怎么解?

    function find(string){
        let foundA = false;  // 用一个变量标记a是否找到
        for(let c of string){
            if(c==='a')
                foundA = true;
            else if(foundA && c === 'b')   // 在找到a的基础上,找字符b
                return true;
            else  
                foundA = false;   // 如果a没有找到,或者找到a但是后面不是b,则表明ab没找到,将a的标记变量设置为false没找到
        }
        return false; // 循环结束没找到ab,则返回false
      }   
    
   let result = find("i am a girl bcd");
   console.log(result); // true

那问题3:在一个字符串中找到字符‘abcdef’, 怎么解呢?

同问题2,我们可以设置多个变量标识

    function find(string){
        let foundA = false;
        let foundB = false;
        let foundC = false;
        let foundD = false;
        let foundE = false;
        for(let c of string){
            if(c == 'a'){
                foundA = true;
            }else if(foundA && c === 'b'){
                foundB = true;
            }else if(foundB && c === 'c'){
                foundC = true;
            }else if(foundC && c === 'd'){
                foundD = true;
            }else if(foundD && c === 'e'){
                foundE = true;
            }else if(foundE && c === 'f'){
                return true;
            }else{
                foundA = false;
                foundB = false;
                foundC = false;
                foundD = false;
                foundE = false;
            }
        }
        return false
    }

    console.log(find("i am a abcjucabcdef")); // true
    console.log(find("i am a abcjucabdef")); // false

看到这里,我们下面尝试使用状态机实现字符查找

2.2.2 使用状态机解决字符输入查找

在一个字符串中找到字符‘abcdef’, 用状态机解决。
思路:

   function find(string){
        let state =  start;  // state表示当前状态
        for(let c of string){
            state = state(c); //  将state执行的结果,也就是下一个状态赋给当前状态
        }
        return state === end;
    }

    function start(c){
        if(c ==='a'){
            return foundA;
        }else
            return start; 
    }

    // end状态永远返回end,叫做一个trap
    function end(c){  
        return end;
    }

    // foundA 找字符b
    function foundA(c){
        if(c ==='b'){
            return foundB;
        }else{
            return start(c); // 把当前字符传给start从新开始往后找,避免漏掉当前字符。
        }
    }
    
    // foundB 找字符c
    function foundB(c){
        if(c ==='c'){
            return foundC;
        }else{
            return start(c);
        }
    }

    // foundC 找字符d
    function foundC(c){
        if(c ==='d'){
            return foundD;
        }else{
            return start(c);
        }
    }

    // foundD 找字符e
    function foundD(c){
        if(c ==='e'){
            return foundE;
        }else{
            return start(c);
        }
    }

    // foundE 找字符f
    function foundE(c){
        if(c ==='f'){
            return end;
        }else{
            return start(c);
        }
    }

   console.log(find('abcdeabcdefsss')); // true

那用状态机怎么实现在字符串中查找'abababx' ?

// 状态机 处理字符串"abababx"

        function find(string){
            let state = start;
            for(let c of string){
                state = state(c);
            }
            return state === end;
        }

        function start(c){
            if(c === "a"){
                return foundA;
            }else{
                return start;
            } 
        }
        function end(c){
            return end;
        }

        function foundA(c){
            if(c === "b"){
                return foundB;
            }else{
                return start(c);
            }
        }

        function foundB(c){
            if(c === 'a'){
                return foundA2;
            }else{
                return start(c);
            }
        }
        function foundA2(c){
            if(c === 'b'){
                return foundB2;
            }else{
                return start(c);
            }
        }
        function foundB2(c){
            if(c === 'a'){
                return foundA3;
            }else{
                return start(c);
            }
        }
        function foundA3(c){
            if(c === 'b'){
                return foundB3;
            }else{
                return start(c);
            }
        }
        function foundB3(c){
            if(c === 'x'){
                return end;
            }else{
                return foundB2(c);
            }
        }



        console.log(find("i am abababx")); // true
        console.log(find("i am ababababx")); // true
        console.log(find("i am abcabcababx")); // false
上一篇 下一篇

猜你喜欢

热点阅读