English 中文(简体)
javascript计时问题
原标题:javascript timing issues

我正在处理数据。我设置了一个worker函数,它由<code>setInterval</code>每隔5毫秒调用一次。我正在计算函数运行所需的时间,从0到1ms。我还在计算函数实际调用的速度以及大约80毫秒。

我的问题是,如果运行这个函数只需要1ms,而我每5ms调用一次,为什么它每80ms调用一个?

我确实有第二个辅助函数根据处理函数正在做的当前数据更新画布,但它在自己的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);
最佳回答

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

问题回答

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





相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.

热门标签