Javascript函数调用两次,如何处理?

Javascript函数调用两次,如何处理?,javascript,Javascript,我的应用程序是用C#和ASP.NET开发的LiveChat 我有一个客户端计时器,它每秒调用webservice函数RetrieveMessages()。 此外,在用户发送消息后不久,我将调用de same函数RetrieveMessages() 我有一个存储最后一个消息Id的变量,因此,每个RetrieveMessage调用只检索未读的消息 有时客户端会两次显示相同的消息,如下所示: 埃沃顿(14:22:20):你好! 埃沃顿(14:22:20):你好 重复性只发生在客户端,数据库表正常,没有

我的应用程序是用C#和ASP.NET开发的LiveChat

我有一个客户端计时器,它每秒调用webservice函数RetrieveMessages()。 此外,在用户发送消息后不久,我将调用de same函数RetrieveMessages()

我有一个存储最后一个消息Id的变量,因此,每个RetrieveMessage调用只检索未读的消息

有时客户端会两次显示相同的消息,如下所示:

埃沃顿(14:22:20):你好! 埃沃顿(14:22:20):你好

重复性只发生在客户端,数据库表正常,没有重复

我怀疑是计时器,发送消息在更新变量lastMessageId之前正在执行RetrieveMessage

如何同步RetrieveMessage()的调用

下面是一些要分析的代码

    // ThisFunction is a callback that RetrieveMessage every time the user send's a message
function SendMessageSucess(cdMsgEnviada) {
    //Carrega Mensagens
    Avalon.Services.ChatService.RetrieveMessages(CodChamado, IdLastMsg, RetrieveMessagesSucess);
}
即时滴答声

    // Every second, verify is exist new messages
function timer_onTick() {
    //Carrega Mensagens
    Avalon.Services.ChatService.RetrieveMessages(CodChamado, IdLastMsg, RetrieveMessagesSucess);
}
RetrieveMessages函数

function RetrieveMessagesSucess(result) {
    var myMsgs = new Array();
    for (var i = 0; i < result.length; i++) {
        var obj = eval('(' + result[i] + ')');
        if (obj != null)
            myMsgs[i] = obj;
    }

    for (var j = 0; j < myMsgs.length; j++) {
        if (myMsgs.length > 0) {
            // Armazeno o codigo da ultima mensagem recebida
            IdLastMsg = myMsgs[myMsgs.length - 1].cd_chat_message;

            if (par) {
                var novoconteudo = "<div style='background-color: #EFEFEF; padding: 10px;'>"
                par = false;
            }
            else {
                var novoconteudo = "<div style='padding: 10px;'>"
                par = true;
            }

            if (myMsgs[j].origem_mensagem == 1) // Msg enviada pelo cliente
                novoconteudo = novoconteudo + "<b>" + myMsgs[j].solicitante + ": </b>"
            else
                novoconteudo = novoconteudo + "<b>" + myMsgs[j].tecnico + ": </b>"

            var objDate = eval(myMsgs[j].datahora.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));

            novoconteudo = novoconteudo + "(" + objDate.format("HH:MM:ss") + ") ";

            novoconteudo = novoconteudo + myMsgs[j].texto + "</div>";

            divChatHistory.append(novoconteudo);

            AutoScroll();

            if (myMsgs[j].origem_mensagem == 2) // Msg enviada por um tecnico
                show_popAlert()
        }
    }
    // Verifico se o chat esta ativo
    IsChatInativo();
}
函数检索消息访问(结果){
var myMsgs=新数组();
对于(变量i=0;i0){
//阿玛泽诺·奥科迪戈·达乌尔蒂玛·勒塞比达酒店
IdLastMsg=myMsgs[myMsgs.length-1].cd_聊天_消息;
如果(标准杆){
var novoconteudo=“”
PAR=假;
}
否则{
var novoconteudo=“”
PAR=真;
}
if(myMsgs[j].origem\u mensage==1)//Msg enviada pelo cliente
novoconteudo=novoconteudo+“”+myMsgs[j].请求者+“”:
其他的
novoconteudo=novoconteudo+“”+myMsgs[j]。tecnico+“”:
var objDate=eval(myMsgs[j].datahora.replace(//\/Date\(\d+)\//gi,“新日期($1)”);
novoconteudo=novoconteudo+”(“+objDate.format(“HH:MM:ss”)+”);
novoconteudo=novoconteudo+myMsgs[j].texto+“”;
divChatHistory.append(novoconteudo);
AutoScroll();
if(myMsgs[j].origem\u mensage==2)//Msg enviada por um tecnico
show_popAlert()
}
}
//验证会话设置
IsChatInativo();
}

有什么想法吗?

当您输入tick方法时,请尝试禁用计时器,并在离开该方法之前重新启用它。

设置作为对象的全局变量,并在每次向对话添加新消息时在其中创建新属性。在新属性的名称中使用消息ID,并将其设置为true或其他值。如果您的每条消息都有一个唯一的ID,那么您可以通过检查对象中是否存在该消息ID的特定属性来验证您在继续之前是否尚未处理该消息

可能看起来像:

var PROCESSED_MSGS = new Object();
然后后来

for (var j = 0; j < myMsgs.length; j++) {
    if (myMsgs.length > 0) {
        thisMsgId = myMsgs[j].id;
        if(PROCESSED_MSGS['msg'+thisMsgId]) continue;
        PROCESSED_MSGS['msg'+thisMsgId] = true;
        //keep going....
for(var j=0;j0){
thisMsgId=myMsgs[j].id;
如果(已处理的消息['msg'+thisMsgId])继续;
已处理的_MSGS['msg'+thisMsgId]=true;
//继续。。。。

Jage,您的解决方案运行良好。我在RetrieveMessages中做了一些调整 让我们看看代码:

    function RetrieveMessagesSucess(result) {
    // parsin the json and storing the messages in a array
    var myMsgs = new Array();
    for (var i = 0; i < result.length; i++) {
        var obj = eval('(' + result[i] + ')');
        if (obj != null)
            myMsgs[i] = obj;
    }


    for (var j = 0; j < myMsgs.length; j++) {
        if (myMsgs.length > 0) {

            // Verifing if the message already exists
            var divExiste = document.getElementById(myMsgs[j].cd_chat_message);

            // If not exists, put the message on the page
            if (divExiste == null) {

                // Storing the id of tha last received message. This is useful as a parameter to retrieve messages again
                IdLastMsg = myMsgs[myMsgs.length - 1].cd_chat_message;

                // Trick to a zebra style
                if (par) {
                    var novoconteudo = "<div id='" + myMsgs[j].cd_chat_message + "' style='background-color: #EFEFEF; padding: 10px;'>"
                    par = false;
                }
                else {
                    var novoconteudo = "<div id='" + myMsgs[j].cd_chat_message + "' style='padding: 10px;'>"
                    par = true;
                }

                // Putting the message on page
                if (myMsgs[j].origem_mensagem == 1) // Msg enviada pelo cliente
                    novoconteudo = novoconteudo + "<b>" + myMsgs[j].solicitante + ": </b>"
                else
                    novoconteudo = novoconteudo + "<b>" + myMsgs[j].tecnico + ": </b>"

                var objDate = eval(myMsgs[j].datahora.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
                novoconteudo = novoconteudo + "(" + objDate.format("HH:MM:ss") + ") ";
                novoconteudo = novoconteudo + myMsgs[j].texto + "</div>";
                divChatHistory.append(novoconteudo);
                AutoScroll();

                if (myMsgs[j].origem_mensagem == 2) // Msg enviada por um tecnico
                    show_popAlert()
            }
        }
    }
    IsChatInativo();
}
函数检索消息访问(结果){
//输入json并将消息存储在数组中
var myMsgs=新数组();
对于(变量i=0;i0){
//正在验证消息是否已存在
var divExiste=document.getElementById(myMsgs[j].cd\u聊天信息);
//如果不存在,请将消息放在页面上
if(divExiste==null){
//存储上次接收到的消息的id。这对于再次检索消息非常有用
IdLastMsg=myMsgs[myMsgs.length-1].cd_聊天_消息;
//斑马风格的把戏
如果(标准杆){
var novoconteudo=“”
PAR=假;
}
否则{
var novoconteudo=“”
PAR=真;
}
//将消息放在页面上
if(myMsgs[j].origem\u mensage==1)//Msg enviada pelo cliente
novoconteudo=novoconteudo+“”+myMsgs[j].请求者+“”:
其他的
novoconteudo=novoconteudo+“”+myMsgs[j]。tecnico+“”:
var objDate=eval(myMsgs[j].datahora.replace(//\/Date\(\d+)\//gi,“新日期($1)”);
novoconteudo=novoconteudo+”(“+objDate.format(“HH:MM:ss”)+”);
novoconteudo=novoconteudo+myMsgs[j].texto+“”;
divChatHistory.append(novoconteudo);
AutoScroll();
if(myMsgs[j].origem\u mensage==2)//Msg enviada por um tecnico
show_popAlert()
}
}
}
IsChatInativo();
}
就是这样,伙计们

非常感谢


请原谅我的英语不好(=o)

您可能应该使用某种形式的comet来处理此类事务。这不会很好地扩展。嗨,Jage,您的解决方案似乎很好。今天我将实现这一点,很快我会给您反馈谢谢您的回答。