ホームページ > 記事 > ウェブフロントエンド > 最初に JS イベントを発行してからサブスクライブする方法
今回は、JS イベントを最初に公開してからサブスクライブする方法について説明します。JS イベントを最初に公開してからサブスクライブするための 注意事項 とは何ですか。
私は以前にeventマネージャーを書いたことがありますが、これは通常の購読してから公開するモデルです。ただし、実際のシナリオでは、後から購読する人も公開されたメッセージを受信できるようにする必要があります。たとえば、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); })私の実際のシナリオでは、メソッド B はイベント A がトリガーされた後にのみ実行できます。ただし、方法 B は方法 C の後に完了する必要があります。つまり、B は A と C の完了に依存します。そして、A はほぼ毎回すぐにトリガーされます。もちろん、2 つのスイッチ
変数 とエージェント関数を設定し、両方のイベントが完了した後に 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 は実行されず、さらに 2 つの変数があります。最後に、コード内のメソッドで、変数と 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();これはより明確になります。イベントのサブスクリプションでは、通話の場所についてあまり心配する必要はありません。上記は、最新の呼び出しパラメーターを記憶しているだけで、後続のサブスクライブされたイベントをトリガーするために使用できます。これは、1 回限りのイベント (サイクルごとに 1 回だけトリガーされるイベント) に適しています。プッシュ メッセージのようなイベントの場合、継続的にトリガーされ、すべての履歴レコードを確実に取得したい場合は、すべてのパラメーターを覚えておく必要があります。これは状況であり、実際にはさらに多くのプロセスの依存関係が存在する可能性があります。もちろん、この記事の事例を読んだ後は、この方法を習得したと思います。さらに興味深い情報については、php 中国語 Web サイトの他の関連記事に注目してください。 推奨読書:
protobuf.jsおよびLong.jsの使用の詳細な説明
以上が最初に JS イベントを発行してからサブスクライブする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。