sinceramente non mi meraviglia piu' di tanto
un setTimeout non manda in "sleep" lo script, qui abbiamo istruzioni che si susseguono runtime
e resta al browser decidere come tenere loro testa
puo' tranquillamente decidere di semplificare mostrando il risultato finale, dopo un' unica temporizzazione di 3000 millisec

puoi fare una cosa del genere
codice:
var dwellTime = 3000;
var backColor = new Array(); // don't change this


backColor[0]  = '#FaFaFa';
backColor[1]  = '#EEEEEE';
backColor[2]  = '#DDDDDD';
backColor[3]  = '#CCCCCC';
backColor[4]  = '#BBBBBB';
backColor[5]  = '#AAAAAA';
backColor[6]  = '#999999';
backColor[7]  = '#888888';
backColor[8]  = '#777777';
backColor[9]  = '#666666';
backColor[10]  = '#555555';
backColor[11]  = '#444444';
backColor[12]  = '#333333';
backColor[13]  = '#222222';
backColor[14]  = '#111111';
backColor[15]  = '#000000';

function flashBG(whichColor){
	document.body.style.backgroundColor = backColor[whichColor];
	var nextStep=((whichColor++)>15)?false:whichColor;
	if(nextStep) setTimeout('flashBG('+nextStep+')',100);
}

var t = setTimeout('flashBG(0)',dwellTime);
e a perderci un po' di tempo fare molto di meglio,
comunque e' il minimo per farlo funzionare

ciao