>웹 프론트엔드 >JS 튜토리얼 >JS 이벤트를 먼저 게시한 후 구독하는 방법

JS 이벤트를 먼저 게시한 후 구독하는 방법

php中世界最好的语言
php中世界最好的语言원래의
2018-03-16 11:20:032201검색

이번에는 JS이벤트 먼저 퍼블리싱 후 구독하는 방법을 가져왔습니다. JS 이벤트 퍼블리싱 후 구독을 구현하기 위한 노트는 무엇인가요?

저는 이전에 일반적인 구독 후 게시 모델인 eventmanager를 작성한 적이 있습니다. 하지만 실제 시나리오에서는 나중에 구독하는 사람도 게시된 메시지를 받을 수 있도록 해야 합니다. 예를 들어 WeChat 공개 계정을 팔로우하면 여전히 역사적인 뉴스를 볼 수 있습니다. QQ 오프라인 메시지와 마찬가지로 제가 먼저 보내드리며, 로그인 후 받으실 수 있습니다. 이벤트를 구독하는 모든 메소드가 실행될 수 있도록 하기 위함입니다.

 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);
        }
    };

실제로 코드 몇 줄만 추가했습니다. 마지막 트리거의 매개변수를 캐시합니다. 그런 다음 핸들을 추가할 때 판단하세요. 구독 시 이미 캐시된 매개변수가 있으면 해당 메서드를 실행할 수 있다는 의미입니다.

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);
})

내 실제 시나리오는 이벤트 A가 트리거된 후에만 메서드 B를 실행할 수 있다는 것입니다. 그러나 방법 B는 방법 C 이후에 완료되어야 합니다. 즉, B는 A와 C의 완성에 의존합니다. 그리고 A는 거의 매번 빠르게 트리거됩니다. 물론 두 개의 스위치 변수와 에이전트 기능을 설정한 다음 두 이벤트가 모두 완료된 후에 B를 실행할 수 있습니다. 코드는 다음과 같습니다.

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();

이 함수가 구현되었지만 가독성이 좋지 않으며 이벤트 구독이 트리거 이전에 있으면 doB가 절대 실행되지 않으며 변수가 두 개 더 있습니다. 마지막으로, 어리석은 것은 변수와 setTimeout을 사용하여 상태 를 결정하는 것입니다. 이로 인해 죽은 루프 가 발생할 수 있습니다.

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事件触发迟

이 방법은 아마도 가장 바람직하지 않을 것입니다. 외부 사건으로 인해 장애가 발생할 수 있으므로 여기서는 벗어날 방법이 없습니다. 마치 구멍을 파는 것과 같습니다. 하지만 이벤트가 먼저 게시하고 나중에 구독하는 것을 지원한다면 문제는 간단할 것입니다.

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();

이것은 훨씬 더 명확할 것입니다. 이벤트 구독은 통화 위치에 대해 크게 걱정할 필요가 없습니다. 위의 내용은 후속 구독 이벤트를 트리거하는 데 사용할 수 있는 가장 최근 호출 매개변수만 기억합니다. 이는 일회성 이벤트(주기당 한 번만 트리거되는 이벤트)에 적합합니다. 푸시 메시지와 같은 이벤트인 경우 지속적으로 트리거됩니다. 모든 기록을 가져올 수 있는지 확인하려면 모든 매개변수를 기억해야 합니다. 이는 실제로 더 많은 프로세스 종속성이 있을 수 있는 상황입니다. 물론 프로세스 제어에는 여러 가지 방법이 있으며 이를 지원하는 라이브러리도 많습니다. Promise 및 async와 같은 것입니다. 이 문서에서는 여러분에게 영감을 줄 수 있는 프로세스 관련 이벤트 및 방법 시나리오만 설명합니다.

이 기사의 사례를 읽은 후 방법을 마스터했다고 생각합니다. 더 흥미로운 정보를 보려면 PHP 중국어 웹사이트의 다른 관련 기사를 주목하세요!

추천 도서:

vue의 사용자 정의 동적 구성 요소 사용에 대한 자세한 설명

protobuf.js 및 Long.js 사용에 대한 자세한 설명

위 내용은 JS 이벤트를 먼저 게시한 후 구독하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.