Home  >  Article  >  Web Front-end  >  How to publish JS events first and then subscribe

How to publish JS events first and then subscribe

php中世界最好的语言
php中世界最好的语言Original
2018-03-16 11:20:032024browse

This time I will bring you JSEventThe method of publishing first and then subscribing, implementing the JS event publishing first and then subscribing What are the precautions, the following is a practical case, let’s take a look take a look.

I wrote an eventmanager before, which is an ordinary subscribe first and publish later model. But in actual scenarios, we need to ensure that those who subscribe later can also receive published messages. For example, if we follow the WeChat public account, we can still see historical news. Similar to QQ offline messages, I will send them to you first, and you can receive them after logging in. It is to ensure that all methods that subscribe to the event can be executed.

 var eventManger = {
        cached: {},
        handlers: {},        //类型,绑定事件 
        addHandler: function (type, handler) {            if (typeof handler !== "function") return;            if (typeof this.handlers[type] == "undefined") {                this.handlers[type] = [];
            }            this.handlers[type].push(handler);            if (this.cached[type] instanceof Array) {                //说明有缓存的 可以执行
                handler.apply(null, this.cached[type]);
            }
        },
        removeHandler: function (type, handler) {            var events = this.handlers[type];            for (var i = 0, len = events.length; i < len; i++) {                if (events[i] == handler) {
                    events.splice(i, 1);                    break;
                }
            }
        },
        trigger: function (type) {            //如果有订阅的事件,这个时候就触发了
            if (this.handlers[type] instanceof Array) {                var handlers = this.handlers[type];                var args = Array.prototype.slice.call(arguments, 1);                for (var i = 0, len = handlers.length; i < len; i++) {
                    handlers[i].apply(null, args);
                }
            }            //默认缓存
            this.cached[type] = Array.prototype.slice.call(arguments, 1);
        }
    };

In fact, it just adds a few lines of code. Cache the parameters of the last trigger. Then make a judgment when adding handle. If there are already cached parameters when subscribing, it means that the method can be executed.

eventManger.addHandler("test", function (res) {
    console.log("先订阅,后发布1", res);
})
eventManger.trigger("test", 2);
eventManger.addHandler("test", function (res) {
    console.log("先发布,后订阅2", res);
})
eventManger.addHandler("test", function (res) {
    console.log("先发布,后订阅3", res);
})

My actual scenario is that method B can only be executed after event A is triggered. But method B needs to be completed after method C. That is, B depends on the completion of A and C. And A will be triggered quickly almost every time. Of course, you can set up two switches variables and an agent function, and then do B after both events are completed. The code is as follows:

var aReady = false;var cReady = false;
eventManger.addHandler("A", function () {
    aReady = true;
    console.log("do A");
    proxyC();
});
eventManger.trigger("A", 2);function doB() {
    console.log("do B");    //实际B中的方法需要在A事件成功之后才能执行}function doC() {
    console.log("do C");
    cReady = true;
    proxyC();
}function proxyC() {
    aReady && cReady && doB();
}
doC();

This function is implemented, but the readability is poor, and the event subscription must be in the right position. If it is before the trigger, doB will never be executed, and there are two more variables in the code and One method, the most stupid one is to use a variable plus setTimeout to determine the status, which may lead to a dead loop.

var aReady = false;
eventManger.addHandler("A", function () {
    aReady = true;
    console.log("do A");
});function doB() {
    console.log("do B");    //实际B中的方法需要在A事件成功之后才能执行}function doC() {
    console.log("do C");    if (!aReady) {
        console.log("wating...");        setTimeout(doC, 50);        return;
    }
    doB();
}
doC();
eventManger.trigger("A", 2);//模拟A事件触发迟

This method is the most undesirable. Because external events may cause failure, there is no way out here. It's like digging a hole. But if the event supports publishing first and subscribing later, the problem will be simple:

eventManger.trigger("A", 2);function doB() {
    console.log("do B");    //实际B中的方法需要在A事件成功之后才能执行}function doC() {
    console.log("do c");
    eventManger.addHandler("A", function () {
        console.log("do a");
        doB();
    });
}
doC();

This will be much clearer. Event subscriptions don’t have to worry so much about the location of the call. The above just remembers the most recent call parameters, which can be used to trigger subsequent subscribed events. This is suitable for one-time events (events that will only be triggered once per cycle). If it is an event like a push message, it will be triggered continuously. If you want to ensure that you can get all the history records, you need to remember all the parameters. This is a situation; there may actually be more process dependencies. Of course, there are many methods for Process Control, and there are many library supports. Such as promise and async. This article only explains a process-related scenario of events and methods, which may be inspiring to you.

I believe you have mastered the method after reading the case in this article. For more exciting information, please pay attention to other related articles on the php Chinese website!

Recommended reading:

Detailed explanation of the use of custom dynamic components in vue

Usage of protobuf.js and Long.js Detailed explanation

The above is the detailed content of How to publish JS events first and then subscribe. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn