Lesson 17 / الدرس 17

Promises / الوعود

The receipt the browser hands you when you ask for something that takes time. It is not the value; it is an object that will eventually hold either the value or the reason there is not one.

الإيصال الذي يعطيك إياه المتصفح حين تطلب شيئًا يستغرق وقتًا. وهو ليس القيمة؛ بل كائن سيحمل في النهاية إما القيمة وإما سبب عدم وجودها.

Three states, one direction

pending      still waiting
fulfilled    finished, with a value      -> .then(value => ...)
rejected     finished, with a reason     -> .catch(err => ...)

a promise settles once and never changes again

.then(fn)      run fn when it works, and return a NEW promise
.catch(fn)     run fn when anything above it failed
.finally(fn)   run fn either way — cleanup, hiding a spinner
The last section of the demonstration is the same three dependent steps that were nested three deep at the end of lesson 16, written flat. The chain reads top to bottom in the order it happens, and there is one error handler for all three steps rather than three copies of the same check.

Several at once

CombinatorSettles whenYou get
Promise.allAll succeed, or one failsAn array of values, or the first error
Promise.allSettledAll finish, however they finishOne entry each: status and value or reason
Promise.raceThe first one settlesThat one result, good or bad
Promise.anyThe first one succeedsThat value; fails only if all fail

These matter more than they look. Three requests in a row take the sum of their times; Promise.all([a, b, c]) starts all three and takes the time of the slowest, which is often three times faster for no extra work. Use all when you need every piece and allSettled when a partial answer is still useful — a dashboard of six panels should show the five that loaded, not nothing.

Two more things the demonstration shows in passing. Printing the promise itself gives you [object Promise], not the value — a promise is never the thing, and no amount of reading it will make it become the thing. And the lines after the request run immediately, before any result arrives, which is exactly the gap lesson 15 described. Everything that depends on the result must live inside a .then, or, from the next lesson, after an await.

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

Preview / المعاينة

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

1. What do you get when you print a promise instead of its value?

2. What happens if you forget return inside a .then?

3. When is Promise.allSettled better than Promise.all?

Your task / مهمتك

Write a delay(ms, value) that returns a promise, and use it to build a chain of three dependent steps that prints a timestamped line at each one. Make the middle step reject and prove two things: the third step never ran, and one .catch caught it. Add a .finally that reports the total elapsed time. Then run three independent delays both ways — one after another, and through Promise.all — and print both totals.

اكتب delay(ms, value) تُعيد وعدًا، واستخدمها لبناء سلسلة من ثلاث خطوات متعاقبة تطبع سطرًا موقّتًا عند كل واحدة. واجعل الخطوة الوسطى ترفض وأثبت أمرين: أن الخطوة الثالثة لم تعمل قط، وأن .catch واحدة التقطتها. وأضف .finally تبلّغ الزمن الكلي المنقضي. ثم شغّل ثلاثة تأخيرات مستقلة بالطريقتين — واحدًا بعد آخر، وعبر Promise.all — واطبع المجموعين.

  • A delay() returning a promise delay() تُعيد وعدًا
  • A three-step chain with timestamps سلسلة من ثلاث خطوات بطوابع زمنية
  • A rejection caught once, with the third step skipped رفض مُلتقط مرة والخطوة الثالثة متخطاة
  • Sequential and Promise.all totals compared مجموعا التتابع وPromise.all مقارَنين
How do you want to submit? / كيف تريد التسليم؟