Skip to content
JavaScript js control-flow 4 min read

while & do...while

Sometimes you need to repeat work until something changes — not a fixed number of times, but “as long as a condition holds.” That is exactly what while and do...while express. Unlike a for loop, which leans toward counting, these condition-driven loops shine when you do not know up front how many iterations you will need. The catch: if the condition never becomes false, the loop runs forever, so controlling that condition is everything.

The while loop

A while loop checks its condition before each pass. If the condition is truthy, the body runs; then the condition is checked again. The moment it evaluates to falsy, the loop ends and execution continues after it. Because the test comes first, a while body may run zero times.

let countdown = 3;

while (countdown > 0) {
  console.log(countdown);
  countdown--;
}

console.log("Liftoff!");

Output:

3
2
1
Liftoff!

The key is that something inside the body changes the condition — here countdown-- moves it toward 0. Forget that, and you have an infinite loop.

while is a natural fit when the number of iterations depends on data rather than a counter, such as consuming items until a queue is empty.

const queue = ["build", "test", "deploy"];

while (queue.length > 0) {
  const task = queue.shift();
  console.log(`Running: ${task}`);
}

Output:

Running: build
Running: test
Running: deploy

The do…while loop

A do...while loop runs its body first, then checks the condition. This guarantees the body executes at least once, even if the condition is false from the start. Note the required semicolon after the closing while (...).

let input = 0;

do {
  console.log(`Attempt with value ${input}`);
  input++;
} while (input < 0);

Output:

Attempt with value 0

Even though input < 0 was never true, the body still ran once. This “run at least once” behavior is the entire reason to choose do...while. A classic use is prompting until the answer is valid, where you must ask before you can check.

// Browser example: ask at least once, repeat until a number is entered
let value;

do {
  value = Number(prompt("Enter a positive number:"));
} while (Number.isNaN(value) || value <= 0);

console.log(`You entered: ${value}`);

Choosing between them

Both loops test a condition; the difference is purely when the test happens, which decides whether the body can be skipped entirely.

Featurewhiledo...while
Condition checkedBefore each iterationAfter each iteration
Minimum runs01
Best for”Maybe run, while true""Run, then repeat while true”
Trailing semicolonNoYes, after while (...)

Reach for while when the body should not run if the condition is already false (processing an empty queue should do nothing). Reach for do...while when the first iteration must always happen — reading input, retrying an operation, or generating an initial value before validating it.

Avoiding infinite loops

An infinite loop happens when the condition never becomes falsy. Three things must line up for a loop to terminate: the condition must start true, the body must change a value the condition depends on, and that change must move toward making the condition false.

// ❌ Infinite: i never changes, so i < 5 is always true
let i = 0;
while (i < 5) {
  console.log(i);
  // forgot i++
}

The fix is to update the controlling variable each pass:

let i = 0;
while (i < 5) {
  console.log(i);
  i++; // progresses toward i === 5
}

Warning: A truly infinite loop will freeze the browser tab (and block the UI thread) or peg a Node process at 100% CPU. When experimenting, add a safety counter that breaks after a sane maximum so a logic mistake cannot lock everything up.

let ticks = 0;
const MAX = 1000;

while (someCondition()) {
  doWork();

  if (++ticks > MAX) {
    console.warn("Aborting: too many iterations");
    break;
  }
}

You can deliberately write while (true) for an event or game loop, but only when there is a guaranteed break (or return) inside that exits on a real condition. An intentional infinite loop without an exit path is still a bug.

Best Practices

  • Make sure the body changes a value the condition checks, or the loop will never end.
  • Prefer while when the loop may need to run zero times; use do...while only when the first pass must always happen.
  • Don’t forget the trailing semicolon after do...while’s condition.
  • For an unbounded loop, add a maximum-iteration guard with break so a bug cannot hang the runtime.
  • Keep the controlling logic simple — if you are really counting, a for loop usually reads more clearly.
  • Use while (true) with an explicit internal break/return rather than a contrived always-true condition.
Last updated June 1, 2026
Was this helpful?