時間戳與唯一標識


比較懶,好久沒寫博客了,昨天遇到個問題隨手記錄一下

以前沒遇到這個問題,一直以為時間戳是可以作為類似於主鍵一樣的唯一標識。直到昨天遇到個老項目,出了個奇怪的bug。

項目是別人做的老項目,我們在修改,昨天測試告知說某輸入框,有時候能輸入東西,有時候內容會被清空。

看了頁面,清空的很明顯是表單驗證控件類型錯誤,本來該是單純必填的文本,變成了數字。問題在於這個有時候會變,有時候不會。

該開始對於問題的定位方向不對,以為是所用插件版本過老,插件的問題。

費老大勁查看壓縮的代碼、跟斷點,卻發現所有調用控件的,都是有控件特定class的元素,並沒有問題,然后懷疑不是插件問題,是調用之前就出問題了。

在插件數字控件numberbox初始化的地方用了console.trace(),查看調用棧

發現第一次非控件調用文件是utils.js 進去以后查看代碼,果然發現了問題
function initValidatebox(parent) {
    var children = parent.find(".easyui-validatebox,.easyui-combobox,.easyui-combo,.easyui-combotree,.easyui-combogrid,.easyui-numberbox,.easyui-datebox,.easyui-datetimebox,.easyui-spinner,.easyui-numberspinner,.easyui-timespinner");
    if (children && children.length > 0) {
        $.each(children, function(i, n) {
            if ($(n).attr("data-options")) {
                var vali_rule = eval("[{" + $(n).attr("data-options") + "}]")[0];
                var ntime = new Date().getTime();
                $(n).attr("autovali", ntime);
                var ecss = [];
                var csss = $(n).attr("class").split(" ");
                $.each(csss, function(ci, css) {
                    if (css.indexOf("easyui") > -1) {
                        ecss.push(css.replace("easyui-", ""));
                    }
                });

                if (ecss && ecss.length > 0) {
                    $.each(ecss, function(ci, css) {
                        try {
                            eval("$('[autovali=\"" + $(n).attr("autovali") + "\"]')" + "." + css).apply($('[autovali="' + $(n).attr("autovali") + '"]'), [ vali_rule ]);
                        } catch (e) {
                        }
                    });
                }
            }
        });
    }
}
//方法不復雜,關鍵在於下面的幾行代碼
var ntime = new Date().getTime();
$(n).attr("autovali", ntime);
.
.
.
eval("$('[autovali=\"" + $(n).attr("autovali") + "\"]')" + "." + css).apply($('[autovali="' + $(n).attr("autovali") + '"]'), [ vali_rule ]);
//可以看到加了一個屬性,值為時間戳。"." + css 和apply是調用插件和綁定對象,這不是重點,重點是他選擇元素的的使用使用時間戳為選擇依據

意識到問題所在,驗證是否正確。把斷點打在這個方法里,多次觸發,直到出現bug時慢慢跟。頓時發現錯誤原因

原來,在代碼中時間戳並不唯一。應該是現如今電腦運行速度已經很快,循環中兩個相鄰元素加上的時間戳有可能一樣。

 

這就導致了當循環到第二個元素(市場價),給其初始化時,$('[autovali=\"" + $(n).attr("autovali") + "\"]')選擇了兩個元素,

從而導致前一個元素(屬性名稱)使用的控件種類(文本),被后一個元素的控件種類(數字)覆蓋。也就導致了時隱時現的bug。畢竟並不是每一次循環都出現相鄰元素加上的時間戳一樣。

問題找到就好解決了,我選擇最省時省力的

//$(n).attr("autovali", ntime);
$(n).attr("autovali", ntime + "" + Math.floor(Math.random()*1000));
//把標識由時間戳,改為時間戳加隨機1-3位的數字

 

總結,時間戳並不適合單獨作為唯一標識,尤其是循環中加的時間戳

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM