javascript计时问题

| 我正在处理数据。我设置了一个工作函数,即每5ms被
setInterval
调用。我正在计算该函数运行所花费的时间,从0到1ms。我还在计算实际调用函数的速度及其大约80ms。 我的问题是,如果仅需要1毫秒即可运行该函数,而我每5毫秒调用一次,为什么每80毫秒调用一次呢? 我确实有第二个辅助函数,根据处理函数正在处理的当前数据来更新画布,但是它在自己的setInterval中运行。 这些数字是在Chrome中获取的。我也已经在Opera,Safari,FF3和FF4中进行了测试,尽管调用时间不同,但问题是相同的。 (所有这些都在Mac上) 我知道此代码在IE中尚不可用。我知道其中的一部分很丑。.我还没有开始清理代码...第77到84行是
setInterval
调用。 您可以在此处看到一个有效的示例。
(function ($) {
    var methods = {
        init: function (options) {
            return this.each(function () {
                var $this = $(this);
                $this.addClass(\'ansiScreen\');
                var data = $this.data(\'ansi\');
                if (!data) {
                    data = new Object();
                    data.target = $this;
                    data.fontheight = 16; //12, 16, 22
                    data.fontwidth = Math.round(data.fontheight * 0.6) - 1;
                    data.canvas = $(\'<canvas width=\"\' + (data.fontwidth * 80) + \'px\" height=\"\' + (data.fontheight * 25) + \'px\">\');
                    $this.append(data.canvas);
                    data.ctx = data.canvas[0].getContext(\'2d\');
                    data.ctx.font = data.fontheight + \'px Courier New\';
                    data.processInterval = null;
                    data.screenInterval = null;
                    data.ansi = null;
                    data.ansiCode = null;
                    data.ansiPos = 0;
                    data.fgcolor = \'rgb(170, 170, 170)\';
                    data.bgcolor = \'rgb(0, 0, 0)\';
                    data.bold = false;
                    data.blink = false;
                    data.pos = [0, 0];
                    data.savepos = [0, 0];
                    data.screen = Array();
                    data.last = 0;
                    for (var i = 0; i < 25; i++) {
                        data.screen.push(Array());
                        for (var j = 0; j < 80; j++) {
                            data.screen[i].push([data.bgcolor, data.fgcolor, \' \']);
                        }
                    }
                    $this.data(\'ansi\', data);
                }
            });
        },
        destroy: function () {
            return this.each(function () {
                var $this = $(this);
                var data = $this.data(\'ansi\');

                // Clean up
                $(window).unbind(\'.ansi\');
                data.tooltip.remove();
                $this.removeData(\'ansi\');
            });
        },
        load: function (ansiUrl) {
            return this.each(function () {
                var $this = $(this);
                var me = this;
                $.ajax({
                    \'url\': ansiUrl,
                    \'data\': \'text\',
                    beforeSend: function (jqXHR, settings) {
                        jqXHR.overrideMimeType(\'text/plain; charset=x-user-defined\');
                    },
                    success: function(ansiData) {
                        var data = $this.data(\'ansi\');
                        if (data.processInterval != null) {
                            clearInterval(data.processInterval);
                            clearInterval(data.screenInterval);
                        }

                        data.ansi = ansiData;
                        data.ansiPos = 0;
                        data.fgcolor = \'rgb(170, 170, 170)\';
                        data.bgcolor = \'rgb(0, 0, 0)\';
                        data.bold = false;
                        data.blink = false;
                        data.pos = [0, 0];
                        data.savepos = [0, 0];

                        var interval = setInterval(function () {
                            processAnsi.call(me);
                        }, 5);
                        data.processInterval = interval;
                        interval = setInterval(function () {
                            updateDisplay.call(me);
                        }, 30);
                        data.screenInterval = interval;
                        $this.data(\'ansi\', data);
                        updateDisplay.call(me);
                    }
                });
            });
        }
    };

    $.fn.ansi = function (method) {
        // Method calling logic
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === \'object\' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error(\'Method \' + method + \' does not exist on jQuery.ansi\');
        }
    };

    // Process a byte from teh ansi data
    function processAnsi() {
        var start = new Date().getTime();
        var $this = $(this);
        var data = $this.data(\'ansi\');

        if (data.ansiPos > data.ansi.length)
        {
            clearInterval(data.processInterval);
            clearInterval(data.screenInterval);
            return;
        }

        var code = data.ansi.charCodeAt(data.ansiPos) & 0xff;
        var char = data.ansi[data.ansiPos];
        data.ansiPos += 1;
        var now = new Date().getTime();
        $this.data(\'ansi\', data);

        if (code < 33 || code > 126)
        {
            switch (code)
            {
                case 0: char = \'\'; break;
                case 10: char = \'\'; cursorStartOfLine.call(this); break;
                case 13: char = \'\'; cursorDown.call(this, 1); break;
                case 27: char = ansiCode.call(this); break;
                case 32: char = \' \'; break;
                case 176: char = \'\\u2591\'; break;
                case 177: char = \'\\u2592\'; break;
                case 178: char = \'\\u2593\'; break;
                case 179: char = \'\\u2502\'; break;
                case 185: char = \'\\u2563\'; break;
                case 186: char = \'\\u2551\'; break;
                case 187: char = \'\\u2557\'; break;
                case 188: char = \'\\u255D\'; break;
                case 191: char = \'\\u2510\'; break;
                case 192: char = \'\\u2514\'; break;
                case 193: char = \'\\u2534\'; break;
                case 194: char = \'\\u252C\'; break;
                case 195: char = \'\\u251C\'; break;
                case 196: char = \'\\u2500\'; break;
                case 197: char = \'\\u253C\'; break;
                case 180: char = \'\\u2524\'; break;
                case 200: char = \'\\u255A\'; break;
                case 201: char = \'\\u2554\'; break;
                case 204: char = \'\\u2560\'; break;
                case 205: char = \'\\u2550\'; break;
                case 215: char = \'\\u256B\'; break;
                case 217: char = \'\\u2518\'; break;
                case 218: char = \'\\u250C\'; break;
                case 219: char = \'\\u2588\'; break;
                case 220: char = \'\\u2584\'; break;
                case 221: char = \'\\u258C\'; break;
                case 222: char = \'\\u2590\'; break;
                case 223: char = \'\\u2580\'; break;
                case 250: char = \'\\u2022\'; break;
                case 254: char = \'\\u25a0\'; break;
                default: char = \'\'; var s = String.fromCharCode(code);  break;
            }
        }

        if (char === undefined) { 
            char = \'[\' + char + \']\';
        }
        if (char != \'\') {
            putCharacter.call(this, char);
        }

        var end = new Date().getTime();
        $(\'#processTime\').html(\'Requested Speed: 5ms, Process Speed: \' + (now-data.last) + \'ms, Process Time: \' + (end-start) + \'ms, Process Position: \' + data.ansiPos + \' of \' + data.ansi.length);
        data = $this.data(\'ansi\');
        data.last = now;
        $this.data(\'ansi\', data);
    }

    function ansiCode() {
        var $this = $(this);
        var data = $this.data(\'ansi\');
        if (data.ansiPos > data.ansi.length)
            return \'-\';

        var valid = /^[0-9;HABCDRsuJKmh]$/;
        var end = /^[HABCDRsuJKmh]$/;
        var char = data.ansi[data.ansiPos];
        var escape = \'\';
        if (char == \'[\')
        {
            var stop = false;
            do {
                data.ansiPos += 1;
                var char = data.ansi[data.ansiPos];
                escape += char;
                stop = end.test(char);
            } while (valid.test(char) && !stop)
            data.ansiPos += 1;
        }

        switch(escape[escape.length - 1])
        {
            case \'J\':
                if (escape == \'2J\') {
                    clearDisplay.call(this);
                }
                break;
            case \'A\':
                var lines = parseInt(escape.substring(0, escape.length - 1));
                if (isNaN(lines)) { lines = 1; }
                data.pos[1] -= lines;
                if (data.pos[1] < 0) { data.pos[1] = 0; }
                break;
            case \'B\':
                var lines = parseInt(escape.substring(0, escape.length - 1));
                if (isNaN(lines)) { lines = 1; }
                cursorDown.call(this, lines);
                break;
            case \'C\':
                var spaces = parseInt(escape.substring(0, escape.length - 1));
                if (isNaN(spaces)) { spaces = 1; }
                cursorForward.call(this, spaces);
                break;
            case \'D\':
                var lines = parseInt(escape.substring(0, escape.length - 1));
                if (isNaN(lines)) { lines = 1; }
                data.pos[0] -= lines;
                if (data.pos[0] < 0) { data.pos[0] = 0; }
                break;
            case \'H\':
                var codes = escape.substring(0, escape.length - 1).split(\';\');
                if (isNaN(codes[0])) { codes[0] = 1; }
                if (isNaN(codes[1])) { codes[1] = 1; }
                data.pos[0] = codes[1] - 1;
                data.pos[1] = codes[0] - 1;
                break;
            case \'s\':
                data.savepos[0] = data.pos[0];
                data.savepos[1] = data.pos[1];
                break;
            case \'u\':
                data.pos[0] = data.savepos[0];
                data.pos[1] = data.savepos[1];
                break;
            case \'m\':
                var codes = escape.substring(0, escape.length - 1).split(\';\');
                for (var i=0; i < codes.length; i++) {
                    var code = codes[i];
                    switch (code) {
                        case \'0\':
                            data.bold = false;
                            data.blink = false;
                            data.fgcolor = \'rgb(170, 170, 170)\';
                            data.bgcolor = \'rgb(0, 0, 0)\';
                            break;
                        case \'1\':
                            data.bold = true;
                            break;
                        case \'5\':
                            data.blink = true;
                            break;
                        case \'30\':
                            data.fgcolor = !data.bold ? \'rgb(0, 0, 0)\' : \'rgb(85, 85, 85)\';
                            break;
                        case \'31\':
                            data.fgcolor = !data.bold ? \'rgb(170, 0, 0)\' : \'rgb(255, 85, 85)\';
                            break;
                        case \'32\':
                            data.fgcolor = !data.bold ? \'rgb(0, 170, 0)\' : \'rgb(85, 255, 85)\';
                            break;
                        case \'33\':
                            data.fgcolor = !data.bold ? \'rgb(170, 85, 0)\' : \'rgb(255, 255, 0)\';
                            break;
                        case \'34\':
                            data.fgcolor = !data.bold ? \'rgb(0, 0, 170)\' : \'rgb(85, 85, 255)\';
                            break;
                        case \'35\':
                            data.fgcolor = !data.bold ? \'rgb(170, 0, 170)\' : \'rgb(255, 85, 255)\';
                            break;
                        case \'36\':
                            data.fgcolor = !data.bold ? \'rgb(0, 170, 170)\' : \'rgb(85, 255, 255)\';
                            break;
                        case \'37\':
                            data.fgcolor = !data.bold ? \'rgb(170, 170, 170)\' : \'rgb(255, 255, 255)\';
                            break;
                        case \'40\':
                            data.bgcolor = !data.bold ? \'rgb(0, 0, 0)\' : \'rgb(85, 85, 85)\';
                            break;
                        case \'41\':
                            data.bgcolor = !data.bold ? \'rgb(170, 0, 0)\' : \'rgb(255, 85, 85)\';
                            break;
                        case \'42\':
                            data.bgcolor = !data.bold ? \'rgb(0, 170, 0)\' : \'rgb(85, 255, 85)\';
                            break;
                        case \'43\':
                            data.bgcolor = !data.bold ? \'rgb(170, 85, 0)\' : \'rgb(255, 255, 0)\';
                            break;
                        case \'44\':
                            data.bgcolor = !data.bold ? \'rgb(0, 0, 170)\' : \'rgb(85, 85, 255)\';
                            break;
                        case \'45\':
                            data.bgcolor = !data.bold ? \'rgb(170, 0, 170)\' : \'rgb(255, 85, 255)\';
                            break;
                        case \'46\':
                            data.bgcolor = !data.bold ? \'rgb(0, 170, 170)\' : \'rgb(85, 255, 255)\';
                            break;
                        case \'47\':
                            data.bgcolor = !data.bold ? \'rgb(170, 170, 170)\' : \'rgb(255, 255, 255)\';
                            break;
                        default:
                            $(\'#debug\').html($(\'#debug\').html() + \'<br>Unknown Attribute: \' + code);
                            break;
                    }
                }
                break;
            default:
                $(\'#debug\').html($(\'#debug\').html() + \'<br>\' + escape);
                break;
        }

        $this.data(\'ansi\', data);
        return \'\';
    }


    // Move the cursor position up a number of lines
    function cursorStartOfLine(lines) {
        var $this = $(this);
        var data = $this.data(\'ansi\');
        data.pos[0] = 0;
        $this.data(\'ansi\', data);
    }

    // Move the cursor position up a number of lines
    function cursorDown(lines) {
        var $this = $(this);
        var data = $this.data(\'ansi\');
        data.pos[1] += lines;
        if (data.pos[1] > data.screen.length - 1) {
            data.pos[1] = data.screen.length - 1;

            for (var i = 0, length1 = data.screen.length - 1; i < length1; ++i) {
                var a = data.screen[i]; // cache object
                var b = data.screen[i+1]; // cache object
                for (var j = 0, length2 = a.length; j < length2; ++j) {
                    a[j] = b[j];
                }
            }

            for (var j = 0, length2 = a.length; j < length2; ++j) {
                data.screen[data.screen.length-1][j] = [\'#000000\', \'#ffffff\', \' \'];
            }

        }
        $this.data(\'ansi\', data);
    }

    // Move the cursor position back a number of columns
    function cursorBack(cols) {
        var $this = $(this);
        var data = $this.data(\'ansi\');
        data.pos[0] -= cols;
        if (data.pos[0] < 0) { data.pos[0] = 0; }
        $this.data(\'ansi\', data);
    }

    // Move the cursor position forward a number of columns
    function cursorForward(cols) {
        var $this = $(this);
        var data = $this.data(\'ansi\');
        data.pos[0] += cols;
        if (data.pos[0] > data.screen[0].length - 1) {
                //data.pos[0] = data.screen[0].length - 1;
                data.pos[0] = 0;
                cursorDown.call(this,1);
        }
        $this.data(\'ansi\', data);
    }

    // Puts a character on screen
    function putCharacter(character) {
        var $this = $(this);
        var data = $this.data(\'ansi\');
        var style = \'background-color:\' + data.bgcolor+\';\';
        style += \'color:\' + data.fgcolor+\';\';
        data.screen[data.pos[1]][data.pos[0]] = [data.bgcolor, data.fgcolor, character, data.blink];
        $this.data(\'ansi\', data);

        // Move forward 1 character
        cursorForward.call(this, 1);
    }

    // Clear the screen
    function clearDisplay() {
        var $this = $(this);
        var data = $this.data(\'ansi\');
        for (var i = 0; i < data.screen.length; i++) {
            for (var j = 0; j < data.screen[i].length; j++) {
                data.screen[i][j] = [data.bgcolor, data.fgcolor, \' \', data.blink];
            }
        }
        data.pos = [0, 0];
        $this.data(\'ansi\', data);
    }

    // Update the container with the current screen
    function updateDisplay() {
        var start = new Date().getTime();
        var $this = $(this);
        var data = $this.data(\'ansi\');

        for (var i = 0, length1 = data.screen.length; i < length1; ++i) {
            var a = data.screen[i]; // cache object
            for (var j = 0, length2 = a.length; j < length2; ++j) {
                data.ctx.fillStyle = a[j][0];
                data.ctx.fillRect (data.fontwidth * j, data.fontheight * i, data.fontwidth, data.fontheight);
                data.ctx.fillStyle = a[j][1];
                data.ctx.textBaseline = \"top\";
                data.ctx.fillText(a[j][2], data.fontwidth * j, data.fontheight * i);
            }
        }

        var end = new Date().getTime();
        $(\'#frameTime\').html(\'Frame Draw Time: \' + (end-start));
    }
})(jQuery);
    
已邀请:
        还要记住,不同的浏览器具有不同的最小间隔。将间隔设置为5ms可能会触发某些浏览器的最小间隔检查。 此外,您运行的计时器越多,浏览器返回队列开始所花费的时间就越长     
        Javascript是单线程的,因此使用setInterval调用的第二个函数会延迟第一个。     

要回复问题请先登录注册