Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【前端笔试题——1】实现消息发布和订阅类 #1

Open
MrpandaLiu opened this issue Apr 13, 2021 · 6 comments
Open

【前端笔试题——1】实现消息发布和订阅类 #1

MrpandaLiu opened this issue Apr 13, 2021 · 6 comments

Comments

@MrpandaLiu
Copy link
Owner

  • 去哪儿网 春招 笔试题

航班列表页面,有筛选组件和列表组件,点击筛选项之后需要刷新列表组件,在用户点击筛选按钮后,会从后端获取到数据,数据到达后,发布一个消息出来,列表组件来订阅这个消息,每到消息接收到的时候,来触发自己的刷新。

class Message {
    // 发送消息,请您实现此函数功能
    dispatch(key, value) {
    }

    // 注册消费者,key表示消息类型名,handler为处理函数,consume表示注册时是否消费历史消息
    on(key, handle, consume) {
    }
}

let n = readInt();
const message = new Message();
for(let i=0; i<n; i++) {
    let key = read_line();
    message.on(key, function(data) {
        console.log(key + ' ' + data.name);
    });
}

let m = readInt();
for(let i=0; i<m; i++) {
    let msg = JSON.parse(read_line());
    let key = read_line();
    message.dispatch(key ,msg);
}

样例输入:
3
rd-1
rd-2
rd-3
2
{name: "aa3"}
rd-3
{name: "aa1"}

样例输出:
rd-3 aa3
rd-1 aa1

@MrpandaLiu
Copy link
Owner Author

MrpandaLiu commented Apr 13, 2021

经大家讨论修改后:

class Message {
    constructor() {
        this.list = {};
    }

    dispatch(key, value) {
        (this.list[key] || []).forEach((handler) => {
            handler(value);
        });
    }

    off(key, handler) {
        this.list[key] = (this.list[key] || []).filter((item) => (item !== handler));
    }

    on(key, handler, consume) {
        let _handler = handler;
        if(consume) {
            _handler = () => {
                handler();
                this.off(key, handler);
            };
        }
        if(!this.list[key]) this.list[key] = [_handler];
        else this.list[key].push(_handler);
    }
}

@gokoururi-git
Copy link

我有两个问题:

  1. this.list = {}?
  2. 这样是不是更好?
dispatch(key, value) {
    this.list[key] && this.list[key].forEach((handler) => {
        handler(value);
    });
}

off(key, handler) {
    this.list[key] = this.list[key] && this.list[key].filter((item) => (item !== handler));
}

@MrpandaLiu MrpandaLiu reopened this Apr 13, 2021
@MrpandaLiu
Copy link
Owner Author

我有两个问题:

  1. this.list = {}?
  2. 这样是不是更好?
dispatch(key, value) {
    this.list[key] && this.list[key].forEach((handler) => {
        handler(value);
    });
}

off(key, handler) {
    this.list[key] = this.list[key] && this.list[key].filter((item) => (item !== handler));
}
  1. 是的 顺手打成数组了 不过数组也是对象嘛hhh
  2. 加上限制鲁棒性更好 (list || []).forEach(...)也可以的

@IsPinocchio
Copy link

 handler = () => {
       handler();
        this.off(key, handler);
};

俺没懂这个handler重定义的里面为什么再调用handler呢

@gokoururi-git
Copy link

 handler = () => {
       handler();
        this.off(key, handler);
};

俺没懂这个handler重定义的里面为什么再调用handler呢

好像是有点问题?这样会不会好点

on(key, handler, consume) {
    let _handler = handler;
    if(consume) {
        _handler = () => {
            handler();
            this.off(key, _handler);
        };
    }
    if(!this.list[key]) this.list[key] = [_handler];
    else this.list[key].push(_handler);
}

@MrpandaLiu
Copy link
Owner Author

 handler = () => {
       handler();
        this.off(key, handler);
};

俺没懂这个handler重定义的里面为什么再调用handler呢

好像是有点问题?这样会不会好点

on(key, handler, consume) {
    let _handler = handler;
    if(consume) {
        _handler = () => {
            handler();
            this.off(key, _handler);
        };
    }
    if(!this.list[key]) this.list[key] = [_handler];
    else this.list[key].push(_handler);
}

正确!这样会造成循环引用,所以应该返回一个副本

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants