Lesson 16 / الدرس 16

Callbacks and timers / ردود النداء والمؤقتات

A function you hand to somebody else to call later. Timers are the simplest place to see one work, and the honest place to see why nesting them stopped being good enough.

دالة تسلّمها لغيرك لينادينها لاحقًا. والمؤقتات أبسط موضع ترى فيه واحدة تعمل، وأصدق موضع ترى فيه لماذا كفّ تعشيشها عن أن يكون كافيًا.

Later, not now

setTimeout(fn, 1000)     run fn once, after about a second
setInterval(fn, 1000)    run fn again and again, about every second

const id = setTimeout(fn, 1000);
clearTimeout(id);        cancel it
clearInterval(id);       stop a repeating one

the number is a MINIMUM delay, not a promise of when
You have already written callbacks: every listener in lesson 6 was one. Timers make the timing visible. The demonstration prints the order things actually happen in, which is never the order they are written in.

Where callbacks stop scaling

getUser(id, function (err, user) {
  if (err) { return show(err); }
  getOrders(user, function (err, orders) {
    if (err) { return show(err); }
    getItems(orders[0], function (err, items) {
      if (err) { return show(err); }
      render(items);                       // finally
    });
  });
});
Three dependent steps, and the code drifts right, the error handling is repeated three times, and the thing it actually does — render some items — is buried deepest. This shape has a name: callback hell. It is not that callbacks are bad; one callback is fine, and you will write them for the rest of your life. It is that sequences of them do not compose. Promises exist to make that same sequence flat, and the next lesson writes exactly this again in four lines.
BeliefReality
setTimeout(fn, 0) runs immediatelyIt runs after all the current code finishes
setTimeout(fn, 1000) runs at 1000msAt the earliest 1000ms — later if the thread is busy
setInterval keeps perfect timeIt drifts, and slow callbacks make it drift more
The page unloading stops timersOnly leaving the page does; hiding an element does not

The second row follows directly from lesson 15: a timer whose moment arrives while the thread is blocked waits its turn like everything else. Timers schedule, they do not interrupt.

Try it live / جرّب بنفسك

Preview / المعاينة

Check yourself / اختبر نفسك

1. When does setTimeout(fn, 0) run?

2. Why does a countdown sometimes accelerate?

3. What is wrong with nesting callbacks three deep?

Your task / مهمتك

Build a countdown from ten that can be started, paused and reset, with the pause resuming from where it stopped rather than restarting. Prove it survives abuse: press start five times in a row and show the countdown still runs at one number per second. Separately, print four numbered lines showing that a setTimeout with a zero delay written in the middle of your code still runs last.

ابنِ عدًّا تنازليًا من عشرة يمكن بدؤه وإيقافه مؤقتًا وتصفيره، على أن يستأنف الإيقاف من حيث توقف لا أن يبدأ من جديد. وأثبت أنه ينجو من الإساءة: اضغط البدء خمس مرات متتالية وأظهر أن العدّ ما زال يسير برقم في الثانية. وعلى حدة، اطبع أربعة أسطر مرقّمة تُظهر أن setTimeout بتأخير صفري مكتوبًا في وسط شيفرتك ما زال يعمل أخيرًا.

  • Start, pause and reset all work البدء والإيقاف والتصفير تعمل كلها
  • Pause resumes, it does not restart الإيقاف يستأنف ولا يبدأ من جديد
  • Five presses do not speed it up خمس ضغطات لا تسرّعه
  • Four numbered lines proving the 0ms timer runs last أربعة أسطر مرقّمة تثبت أن مؤقت الصفر يعمل أخيرًا
How do you want to submit? / كيف تريد التسليم؟