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

时间:2010-02-03 20:03:31

标签: javascript

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

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

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

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

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

双重性只发生在客户端,DataBase表没问题,没有重复。

我怀疑是Timer,发送消息正在更新变量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);
}

OnTImer Tick

    // 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();
}

任何想法?

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

设置一个对象的全局变量,并在向对话添加新消息时在其中创建新属性。在新属性的名称中使用您的消息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....

答案 2 :(得分:0)

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();
}

多数民众赞成。

非常感谢!

原谅我的英语不好= o)