我正在处理数据。我设置了一个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);