JavaScript 计时问题

发布于 2024-11-10 11:19:34 字数 17643 浏览 1 评论 0原文

我正在处理数据。我设置了一个工作函数,由 setInterval 每 5 毫秒调用一次。我正在计算函数运行所需的时间,即 0 到 1 毫秒。我还计算了该函数实际调用的速度,大约为 80 毫秒。

我的问题是,如果运行该函数只需要 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);

Im working on processing data. I setup a worker function thats called every 5ms by setInterval. I'm calculating the amount of time it takes the function to run, its 0 to 1ms. I'm also calculating the speed at which the function is actually invoked and its about 80ms.

My question is, if it takes only 1ms to run through the function, and I'm calling it every 5ms, why is it invoked every 80ms?

I do have a second worker function updating the canvas based on the current data the processing function is doing, but its run in its own setInterval.

These numbers were taken while in Chrome. I've tested in Opera, Safari, FF3 and FF4 as well and the issue is the same, though the invoke time is different. (all this on a mac)

I know this code does not yet work in IE. I know parts of this are ugly.. I haven't started to clean up the code yet... Lines 77 to 84 are the setInterval calls.

You can see a working example here.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

仙气飘飘 2024-11-17 11:19:34

还要记住,不同的浏览器有不同的最小间隔。将间隔设置为 5 毫秒可能会触发某些浏览器的最小间隔检查。
此外,运行的计时器越多,浏览器返回到队列开头所需的时间就越长

Also remember that different browsers have different minimal interval. Setting the interval to 5ms may trigger some browsers minimum interval check.
Additionally, the more timers you have running the longer it's going to take for the browser to get back to the begining of the queue

音栖息无 2024-11-17 11:19:34

Javascript 是单线程的,因此您使用 setInterval 调用的第二个函数会延迟第一个函数。

Javascript is single threaded, so the 2nd function you're calling with setInterval delays the 1st.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文