JavaScript 计时问题
我正在处理数据。我设置了一个工作函数,由 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
还要记住,不同的浏览器有不同的最小间隔。将间隔设置为 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
Javascript 是单线程的,因此您使用 setInterval 调用的第二个函数会延迟第一个函数。
Javascript is single threaded, so the 2nd function you're calling with setInterval delays the 1st.