gpt4 book ai didi

Javascript 发布者/订阅者模式示例

转载 作者:行者123 更新时间:2023-11-30 18:04:49 27 4
gpt4 key购买 nike

我正在学习发布者/订阅者模式,并做了一个简单的例子来更好地理解它。

var Publisher = {
subscribers: {},
Subscribe: function (event, callback) {
if (Publisher[event] && typeof callback === "function") {
if (Publisher.subscribers[event]) {
Publisher.subscribers[event].callbacks.push(callback);
}
else {
Publisher.subscribers[event] = { callbacks: [callback] };
}
}
},
Publish: function (event) {
if (Publisher.subscribers[event].callbacks) {
for (callback in Publisher.subscribers[event].callbacks) {
Publisher.subscribers[event].callbacks[callback].apply(null);
}
}
},

PublishOnClick: function (event, argument) {
Publisher.Publish(event, argument);
}
};

var Subscriber1 = {
initialize: function () {
if (Publisher.Subscribe) {
Publisher.Subscribe("PublishOnClick", Subscriber1.Action);
}
},
Action: function (c) {
document.getElementById('result').innerHTML += "Button Clicked and the count is: " + c;
c++;
}
};
Subscriber1.initialize();


var c = 1;
var fld2 = document.getElementById("myfield2");
if (fld2.addEventListener) {
fld2.addEventListener("click", function() { Publisher.PublishOnClick("PublishOnClick", [c]); }, false);
} else if (fld2.attachEvent) {
fld2.attachEvent("onclick", function() { Publisher.PublishOnClick("PublishOnClick", [c]); });
}

我有一个按钮和局部 View ,我试图通过按钮引发一个事件并在局部 View 上显示计数。我正在获取事件并显示在局部 View 中,但唯一的问题是计数

最佳答案

据我所知,您的问题实际上不在于发布者-订阅者范例。

我想您的设置有点......令人费解,因为从类似的 Angular 来看可能更容易理解:

twitter_feed.tweets = [];
twitter_feed.root_el = document.getElementById("tweets");
twitter_feed.update = function (tweet) {
twitter_feed.tweets.push(tweet);
// demonstration-purposes only -- please don't write live code like this
twitter_feed.root_el.innerHTML += "<p>" + tweet.user + ": \"" + tweet.text + "\"</p>";
};


twitter_data.subscribe("new-tweet", twitter_feed.update);

// some event handler which grabs tweets from AJAX or whatever...
twitter_data.notify("new-tweet", { user : "Me", text : "my new tweet" });

目标是发布者不是对象,而是可以发布数据的对象,而订阅者不是对象,而是可以对已发布事件使用react的对象的扩展...

...无论如何,您的代码适用于手头的范例...

...除了:

Action : function (c) { /* ... */ c++; }

问题是 JS 按 VALUE 而不是按 REFERENCE 传递 SCALAR 数据

所以在你的函数中,当它被调用时,你没有传递:

// .Action(c);
Action (reference_to_c) {
/*...*/.innerHTML = reference_to_c;
reference_to_c++;
}

你实际上通过了:

// .Action(c);
Action (1) {
/*...*/.innerHTML = 1;
1++;
};

JS中的对象是通过引用传递的。 “对象”包括函数和数组。
非对象标量(numberstringbooleannullundefined, NaN) 按值传递,因此如果您有一个参数为标量的函数参数,则在函数内部编辑版本不会更改外部值。

var x = 1,
say_X = function (x) { x += 1; console.log(x); };

say_X(x); // 2;
console.log(x); // 1;

// vs
var obj = { x : 1 },
say_X = function (o) { o.x += 1; console.log(o.x); };

say_X(obj); // 2;
console.log(obj.x); //2;

您在这里真正想做的是让发布者跟踪计数,或者让订阅者跟踪计数,具体取决于这样做的意义所在。
在顶部查看我的 Twitter 示例。

twitter_feed 跟踪它打印到屏幕上的所有推文是有意义的,这样当有新推文出现时,它就会被添加到列表中。
最新的 twitter_data 不会关心以前的推文,所以在这种情况下,订阅者会跟踪状态,而发布者只会监听变化并在发生事情时通知其他人。

在其他情况下,发布者跟踪其状态并向订阅者宣布新状态可能是有意义的:

music_playlist.update_track = function (data) {
music_playlist.current_song.innerHTML = data.current_song;
};
music_player.subscribe("song-change", music_playlist.update_track);
music_player.notify("song-change", { current_song: "Sympathy for the Daleks" });

在这种情况下,播放列表只真正关心更新用户在页面上看到的标题。
音乐播放器正在处理当前可用的歌曲及其当前所处的状态,以及所有其他好东西。

因此您当前问题的解决方案是以下之一:

  1. 使 c 成为 Publisher 的属性,它添加到 c 并随后通知其订阅者
  2. c成为订阅者的属性,Publisher每次通知订阅者的时候,都会在自己的c属性上加上,然后写出来
  3. Action 的参数中取出 c(看起来像 Action : function () {/*...*/} ,这样函数内部的 c 将指向 window.c ...草率,但有效。

这三个中的任何一个都应该可以解决您的问题。

关于Javascript 发布者/订阅者模式示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16051108/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com