JS-事件处理机制

发布订阅设计模式

定义:一种一(发布者)对多(订阅者)的依赖关系,发布者发送改变状态后,所有依赖于它的订阅者都会接收到通知,并由调度中心来执行订阅者的内容(订阅函数)。

// 发布订阅模式的实现
class Event{
    constructor(){
        // 创建调度中心,使用Map提高查找效率
        this.listener = new Map();
    }

    // 注册订阅函数
    on(eventName, fn){
        if(this.listener.has(eventName)){
            this.listener.set(eventName, [...this.listener.get(eventName), fn]);
        }else this.listener.set(eventName, [fn]);
    }

    // 根据事件名称调用响应的订阅函数
    emit(eventName, data){
        if(this.listener.has(eventName)){
            this.listener.get(eventName).forEach(fn =>fn(data));
        }
    }

    off(eventName, fn){
        let fncArr = this.listener.get(eventName);
        if(!fncArr){
            return false;
        }

        // 没有传入则视为置空
        if(!fn){
            fncArr = [];
        }else{
            for(let i=0;i<fncArr.length;i++){
                if(fncArr[i] === fn){
                    fncArr.splice(i,1);
                    break;
                }
            }
        }

        this.listener.set(eventName, fncArr);
    }
}

let event = new Event();

let func = () =>{
    console.log("error");
}

// 注册订阅函数
event.on("test", (data)=>console.log(data));
event.on("test", func);

// 发布者发送数据,由调度中心执行相应的订阅函数
event.emit("test", "hello"); // hello \n error
// 注销订阅函数
event.off("test", func);

event.emit("test", "new") // new

与观察者模式的区别

  1. 发布订阅模式中包含了调度中心,解除了发布者与订阅者的耦合性;同时,可以根据不同主题来添加订阅者,管理更加细化。
  2. 对于观察者模式,可以理解为老师与班级学生的关系,老师布置任务,学生都会被通知执行。
  3. 对于发布订阅模式,可以理解为语文,数学等老师与班级学生的关系,不同的老师布置任务,学生会收到不同的通知,执行不同的任务。

Event Loop

js是一门单线程语言,其异步与多线程的实现是通过 Event Loop 来实现的。

  1. 调用栈
  2. 消息队列(setTimeout、setInterval等的事件回调函数,会在调用栈清空后执行)。
  3. 微任务队列(Promise,async await等创建的异步操作,会在调用栈清空后立即执行,优先于消息队列)。
var p = new Promise(resolve =>{
    console.log(4);
    resolve(5); 
})

function func1(){
    console.log(1);
}

function func2(){
    setTimeout(() =>{
        console.log(2); // 消息队列
    });
    func1();
    console.log(3);
    p.then(x =>{
        console.log(x); // 微任务队列 1
    }).then(() =>{
        console.log(6); // 微任务队列 2
    });
}

func2(); // 4 1 3 5 6 2

事件传播机制和事件代理

事件传播机制

一次事件的发生包含了3个过程:

  1. 事件捕获阶段:从最外层向内查找,构建冒泡阶段需要的传播路线,同时遇到该事件的监听函数就会执行;(父->子)
  2. 事件处理阶段:执行目标元素的监听函数;
  3. 事件冒泡阶段:从目标元素上升,检查经过的节点是否注册该事件的监听函数,有则执行。(子->父)

事件捕获与事件冒泡的选择方式:

// flag 为 true 时方法在事件捕获阶段执行。
// false 则方法在事件冒泡阶段执行。
x.addEventListener("name", func, flag)

事件委托

通过事件的冒泡传播机制,可以发现,如果在一个容器的后代元素中,有很多的相同行为都要处理,则只需要在容器中绑定事件行为即可。通过查找链可以进行方法的调用。

浏览器渲染机制步骤简述

  1. 处理 HTML 标记,构建DOM树;
  2. 处理CSS标记,构建CSSOM树;
  3. 将两树融合为渲染树;
  4. 根据渲染树,在页面进行渲染和解析
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值