请教一下监听事件的原理,监听一个值的变化一般咋实现呀?

一直有个疑惑,监听事件的原理咋实现的,例如不用导网上的模块包,自己写一个监听的项目或者模块包,监听某个值变化了,例如某个数据是否存在变化。

我只能想到While循环,一直扫描触发的时间,当然定时器更好。但定时器的实质还是循环呀。

所以监听值的变化一般咋实现呀while?感觉死循环总感觉资很容易挂。但是我接触过底层单片机也是用 while 实现的,还有PLC,主程序(main)都是一个无限扫描程序。

while,死循环,但感觉对系统不太好(while 内只要有一个小小的 bug 就很致命,我有过几次电脑崩溃重启了)。

> 在此谢谢各位大佬了

阅读 1.5k
3 个回答

一般这种都需要用到具体编程语言开放的 元编程 的能力,从底层去劫持对数据的访问,比如在 js 中的 ProxyObject.defineProperty

const obj = new Proxy({ bar: 1 }, {
    set(...args) {
        console.log('update:', args);
        Reflect.set(...args)
    } 
})

obj.bar = 2; // update: ...

通过上层对已有数据结构做封装也是可行的路径,但需要引入一些概念和约束,会提高使用者的学习成本,比如通过发布订阅模式封装一种数据结构

// 订阅器
class Emitter {
    private __hooks__ = {};

    public on(type, hook) {
        const hooks = this.__hooks__[type] || (this.__hooks__[type] = []);
        hooks.push(hook);
    }

    public emit(type, ...args) {
        const hooks = this.__hooks__[type];
        if (hooks) {
            hooks.forEach((hook) => {
                hook(...args);
            })
        }
    }
}

// 数据类
class Data {
    private __store__ = {};
    
    public emitter = new Emitter();

    constructor(initialData = {}) {
        Object.assign(this.__store__, initialData);
    }

    public get(key) {
        this.emitter.emit('get', key);

        return this.__store__[key];
    }

    public set(key, value) {
        this.__store__[key] = value;

        this.emitter.emit('change', key, value);
    }
}

// 使用
const obj = new Data({
    bar: 1
})
// 订阅数据变化
obj.emitter.on('change', (key, value) => {
    console.log('key changed', key, value);
})

obj.set('bar', 2); // key changed bar 2
class P {
    private int a;
    private Observer observer
    public void setA(int a) {
        this.a = a;
        observer.notifyDataChanged();
   }
}

类似这种,你在需要监听的地方设置个 observer,如果多个地方监听就用list,这样有地方改变了a的值, 别的地方就能知道值改变了

其实就是做一层封装,值得变化只能通过封装后的对象进行修改,从而观察数据的变化。
比如JetPack中的LiveData,只能通过setValue/postValue修改值,每次修改都会触发内部Version的变化,同时封装类有公共监听方法,如LiveData的Observe,值变化时触发订阅就行了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题