Javascript实例变量语法(AJAX页面刷新)

标签 javascript jquery ajax oop syntax

我在使用 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);

这会导致所有消息被一遍又一遍地打印出来。

我知道它还有其他错误,但我现在正在尝试解决的主要问题是实例变量的使用。或者我应该采取其他方法来做到这一点?

更新:更新了代码以反射(reflect)答案,但它仍然不起作用:

$(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 框架来防止这种情况发生?

最佳答案

试试这个:

setInterval($.proxy(messageRefresher, "refresh"), 1000);

问题是您需要确保您的对象(messageRefresher)用作调用“刷新”函数的“上下文”。仅将其声明为原型(prototype)的一部分这一事实并不能确保“this”始终是该对象的实例。事实上,“这个”几乎可以是任何东西。

jQuery 中的(相当新的)“proxy”方法返回对辅助函数的引用,该函数将使用您需要的对象作为上下文(即“refresh”中的“this”)来调用您的函数(“refresh”) ”)。

还有第一行,你只是提到了实例变量,你不需要它;它实际上没有做任何事情。

编辑更多说明。

任何 Javascript 函数内的“this”变量,无论如何或在何处声明,在每次不同的调用时都会获取其值。它不是该功能的永久部分;实际上,它就像传递给函数的有些特殊的参数。

在上面的例子中,您在传递给 $.getJSON 的函数中有一行代码引用“this”。您想要的是让“this”引用表示您的“messageRefresher”对象,对吗?好吧,就目前情况而言,它没有理由具有这样的值(value)。

我不知道为什么你要这样拆分“refreshMessages”。使其成为“刷新”方法。然后,从一开始就保存“this”指针,您就可以从 $.getJSON 处理程序中引用:

MessageRefresher.prototype.refresh = function () {
  var refresher = this;
  $.getJSON('API/read_messages', { room_id: $.getUrlVar('key'), mid: latest_mid }, function (messages) {
    if (messages.length > 0) {
        $("#messages-loading-msg").empty();
        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);
        }
        refresher._latest_mid = messages[2];
    }
    else {
        $("#messages-loading-msg").text("No messages here. Say anything...");
    }

  });
 }  

关于Javascript实例变量语法(AJAX页面刷新),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2594726/

相关文章:

javascript - 如果在 selectAllow 回调中不允许,FullCalendar 禁用选择日期

javascript - 链接点击事件被父 mousedown 事件阻止

jquery - Laravel 5.3 Ajax 登录

javascript - 如何访问 Ajax 调用中的变量集

javascript - jsfiddle jquery ajax 没有按预期返回数据

javascript - MochaJS - 在其他文件中重用 block

javascript - 触发元素/节点列表的更改太慢

php - 将 PHP 变量发送到 JavaScript 函数

javascript - 从另一个方法调用方法时,jQuery 插件 (this) 混淆

javascript - 如何使一个元素只能点击一次,而其他元素在执行操作时仍然可点击?