Рассмотрим следующий блок кода, выполнить несколько раз (jsFiddle):Bizarre do..while поведение: не могли бы вы объяснить?
var length = 50,
xOffset = 0,
yOffset = 0;
for (var a = 0; a < 100; ++a) { // just so we can see it "break"
for (var l = 1; l <= length; l++) {
var percentComplete = l/length,
scaledPercent = (.5 - Math.abs(percentComplete - .5)) * 2,
shake = 0,
shakeTries = 0,
deviationCeil = Math.ceil(10 * scaledPercent);
if (Math.random() < .1 || Math.abs(xOffset) > deviationCeil)
do {
shake = Math.floor(Math.random() * 3) - 1;
if (++shakeTries > 100) throw "X shake exceeded"
}
while (Math.abs(xOffset + shake) > deviationCeil);
xOffset += shake;
shakeTries = 0; // if we set shake = 0 here, everything works!
if (Math.random() < .1 || Math.abs(yOffset) > deviationCeil)
do {
shake = Math.floor(Math.random() * 3) - 1;
if (++shakeTries > 100) throw "Y shake exceeded"
}
while (Math.abs(yOffset + shake) > deviationCeil);
yOffset += shake;
}
}
При запуске повторно, «трясти Y превышена» исключение выбрасывается (далее «трясти X превышена» никогда не выброшены).
Решение состоит в том, чтобы установить shake
в 0 непосредственно перед блоком Y: .
Я не понимаю, почему это должно быть так. В обоих блоках мы начинаем с назначения на тряску, поэтому на самом деле не важно, какой ад был shake
, до перехода в блок do
. Мое понимание do...while
(и причина, по которой я его использую) заключается в том, что он сначала выполняет свой блок перед тестированием условия.
Так почему же это происходит неудачно (не каждый раз), когда я не сбрасываю shake
перед do
блоком?
не могли бы вы правильно отступить от кода – aaronman