【发布时间】:2011-02-05 09:18:30
【问题描述】:
我在使用 Javascript 实例变量时遇到了困难。我正在尝试一种简单的方法来刷新聊天页面,寻找新消息。 AJAX 调用提供mid,或要返回的最低消息ID。这允许调用仅询问最近的消息,而不是所有消息。
MessageRefresher.prototype._latest_mid;
function MessageRefresher(latest_mid) {
this._latest_mid = latest_mid; // it thinks `this` refers to the MessageRefresher object
}
MessageRefresher.prototype.refresh = function () {
refreshMessages(this._latest_mid); // it thinks `this` refers to the window
this._latest_mid++;
}
function refreshMessages(latest_mid) {
$.getJSON('API/read_messages', { room_id: $.getUrlVar('key'), mid: latest_mid }, function (messages) {
for (var i = 0; i < messages[0].length; i++) {
var newChild = sprintf("<li>%s: %s</li>", messages[1][i], messages[0][i]);
$("#messages").append(newChild);
}
});
var messageRefresher = new MessageRefresher(0);
setInterval(messageRefresher.refresh, 1000);
这会导致所有消息被一遍又一遍地打印出来。
我知道它还有其他错误,但我现在要解决的主要问题是实例变量的使用。或者我应该采取其他方法吗?
更新:更新了代码以反映答案,但它仍然不起作用:
$(document).ready(function () {
var messageRefresher = new MessageRefresher(0);
setInterval($.proxy(messageRefresher, "refresh"), 1000);
});
function MessageRefresher(latest_mid) {
this._latest_mid = latest_mid; // it thinks `this` refers to the MessageRefresher object
}
MessageRefresher.prototype.refresh = function () {
refreshMessages(this._latest_mid); // it thinks `this` refers to the window
}
function refreshMessages(latest_mid) {
var refresher = this;
$.getJSON('API/read_messages', { room_id: $.getUrlVar('key'), mid: latest_mid }, function (messages) {
if (messages != null) {
$("#messages-loading-msg").hide();
for (var i = 0; i < messages[0].length; i++) {
var newChild = sprintf("<li>%s: %s</li>", messages[1][i], messages[0][i]);
$("#messages").append(newChild);
}
}
else {
$("#messages-loading-msg").text("No messages here. Say anything...");
}
refresher._latest_mid = messages[2];
});
}
我仍然做错了什么? this 真的指的是messageRefresher,还是proxy?
更新 2: 越来越近了,但还不够:
$(document).ready(function () {
$("#no-js-warning").empty();
messageRefresher = new MessageRefresher(0);
setInterval($.proxy(messageRefresher, "refresh"), 1000);
});
function MessageRefresher(latest_mid) {
this._latest_mid = latest_mid;
}
MessageRefresher.prototype.refresh = function () {
var refresher = this;
$.getJSON('API/read_messages', { room_id: $.getUrlVar('key'), mid: refresher._latest_mid }, function (messages) {
if (messages != null) {
$("#messages-loading-msg").hide();
for (var i = 0; i < messages[0].length; i++) {
var newChild = sprintf("<li>%s: %s</li>", messages[1][i], messages[0][i]);
$("#messages").append(newChild);
}
}
else {
$("#messages-loading-msg").text("No messages here. Say anything...");
}
refresher._latest_mid = messages[2]; // break here
});
}
上面的代码进行了两次 AJAX 调用,然后停止。此外,当我在上面标记的“break here”行上中断时,Firebug 不会显示refresher 或_latest_mid 的值。我是否将refresher 正确传递到闭包中?
更新 3: 现在它不再停止进行 AJAX 调用。也许它有时会进行多次调用的原因是setInterval() 在第一个请求返回之前触发了多个请求并更新了_latest_mid。
如何使用 JQuery Ajax 框架来防止这种情况发生?
【问题讨论】:
-
我不做 jquery,所以我不知道新的 $.proxy 方法的 api,但我保证我的答案在任何框架中都有效。
-
我已经更新了我的答案。您可能想四处寻找一些关于上下文绑定如何在 Javascript 中工作的优秀教程;我输入了一个简短的摘要,但其他人做得比我好。
-
也许您可以在
$.getJSON的响应处理程序中添加一个“setTimeout”调用,而不是使用“setInterval”。换句话说,以超时启动它,然后每当您收到一条消息时,您设置另一个超时以再次执行此操作。这样一来,在完成上一条消息之前,您甚至都不会考虑收到另一条消息。 -
hmm...
setTimeout似乎只触发了一次调用。
标签: javascript jquery ajax oop syntax