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
Several at once
| Combinator | Settles when | You get |
|---|---|---|
| Promise.all | All succeed, or one fails | An array of values, or the first error |
| Promise.allSettled | All finish, however they finish | One entry each: status and value or reason |
| Promise.race | The first one settles | That one result, good or bad |
| Promise.any | The first one succeeds | That 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.
Promise.all([a, b, c]) يبدأ الثلاثة ويأخذ زمن أبطئها، وهو غالبًا أسرع ثلاث مرات بلا عمل إضافي. استخدم all حين تحتاج كل قطعة، وallSettled حين يظل الجواب الجزئي مفيدًا — فلوحة بستة ألواح ينبغي أن تعرض الخمسة التي حُمِّلت لا لا شيء.return داخل .then هو خلل الوعود الكلاسيكي. فبدونه لا تنتظر السلسلة ما بدأته، فتعمل .then التالية فورًا بـundefined ولا يرى معالج خطئك الإخفاق قط. ويبدو الأمر كأن الشيفرة عملت خارج الترتيب بلا سبب. والقاعدة بسيطة: إن بدأت .then شيئًا لاتزامنيًا فأعده. والوعد المرفوض بلا .catch في أي مكان هو الآخر — فالمتصفح يبلّغ عنه كرفض غير معالَج في الطرفية ولا شيء على الصفحة يقول شيئًا البتة.
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.
[object Promise] لا القيمة — فالوعد ليس الشيء أبدًا، ولا قدر من قراءته يجعله يصير الشيء. والأسطر التالية للطلب تعمل فورًا قبل وصول أي نتيجة، وتلك بالضبط الفجوة التي وصفها الدرس 15. وكل ما يعتمد على النتيجة يجب أن يسكن داخل .then، أو، من الدرس التالي، بعد await.new Promise(...) بنفسك. فمعظم ما يستغرق وقتًا يعطيك واحدًا أصلًا — fetch وأكثر واجهات المتصفح الحديثة. والباني لتغليف شيء أقدم لا يتكلم إلا بردود النداء، وهو ما يفعله البيان أعلاه بـsetTimeout.Try it live / جرّب بنفسك
Check yourself / اختبر نفسك
1. What do you get when you print a promise instead of its value?
Everything that depends on the result must live inside a .then, or after an await.
.then أو بعد await.
2.
What happens if you forget return inside a .then?
return داخل .then؟It looks like the code ran out of order for no reason. If a then starts something asynchronous, return it.
3.
When is Promise.allSettled better than Promise.all?
Promise.allSettled أفضل من Promise.all؟all gives you the first error and throws the rest away; allSettled gives you one entry per promise either way.
all يعطيك أول خطأ ويرمي الباقي؛ وallSettled يعطيك مدخلة لكل وعد في الحالين.Score / النتيجة: 0 / 3
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 مقارَنين