이번에는 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!