Imagine that youâre a top singer, and fans ask day and night for your upcoming song.
To get some relief, you promise to send it to them when itâs published. You give your fans a list. They can fill in their email addresses, so that when the song becomes available, all subscribed parties instantly receive it. And even if something goes very wrong, say, a fire in the studio, so that you canât publish the song, they will still be notified.
Everyone is happy: you, because the people donât crowd you anymore, and fans, because they wonât miss the song.
This is a real-life analogy for things we often have in programming:
- A âproducing codeâ that does something and takes time. For instance, some code that loads the data over a network. Thatâs a âsingerâ.
- A âconsuming codeâ that wants the result of the âproducing codeâ once itâs ready. Many functions may need that result. These are the âfansâ.
- A promise is a special JavaScript object that links the âproducing codeâ and the âconsuming codeâ together. In terms of our analogy: this is the âsubscription listâ. The âproducing codeâ takes whatever time it needs to produce the promised result, and the âpromiseâ makes that result available to all of the subscribed code when itâs ready.
The analogy isnât terribly accurate, because JavaScript promises are more complex than a simple subscription list: they have additional features and limitations. But itâs fine to begin with.
The constructor syntax for a promise object is:
let promise = new Promise(function (resolve, reject) {
// â«Ø§ÙÙ
ÙÙÙÙÙØ° (Ø§ÙØ´ÙÙØ±Ø© اÙÙ
ÙÙØªØ¬Ø©Ø Ù
Ø«Ù âØ§ÙÙ
غÙÙÙâ)
});
ØªÙØ¯Ø¹Ù Ø§ÙØ¯Ø§ÙØ© اÙÙ
Ù
Ø±ÙØ±Ø© Ø¥ÙÙ new Promise âØ¨Ø§ÙÙ
ÙÙÙÙÙØ°â. Ù
ت٠صÙÙØ¹ اÙÙØ¹Ø¯ new Promise عÙ
ÙØª Ø§ÙØ¯Ø§ÙØ© تÙÙØ§Ø¦ÙÙØ§. ÙØØªÙÙ ÙØ°Ø§
اÙÙ
ÙÙÙÙÙØ° Ø§ÙØ´ÙÙØ±Ø© اÙÙ
ÙÙØªØ¬ÙØ©Ø ÙÙÙ
ÙÙ Ø£Ù ØªÙØ¯ÙÙ
ÙÙØ§ Ù٠اÙÙÙØ§ÙØ© ÙØ§ØªØ¬Ùا. ÙÙ Ù
ثاÙÙØ§ Ø£Ø¹ÙØ§ÙØ ÙØ§ÙÙ
ÙÙÙÙÙØ° ÙØ°Ø§ ÙÙ âØ§ÙÙ
غÙÙÙâ.
ØªÙØ¯ÙÙ
Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت اÙÙØ³ÙØ·ÙÙ resolve Ù reject ÙÙÙ
ا Ø±Ø¯ÙØ¯ ÙØ¯Ø§Ø¡. ÙÙ
ا ÙÙØ§ ÙØ¶Ø¹ Ø§ÙØ´ÙÙØ±Ø© Ø§ÙØªÙ ÙØ±Ùد تÙÙÙØ°Ùا Ø¥ÙØ§ داخ٠اÙÙ
ÙÙÙÙÙØ°.
ÙØ§ ÙÙÙ
ÙÙØ§ Ù
ØªÙ Ø³ÙØ¹Ø±Ù اÙÙ
ÙÙÙÙÙØ° اÙÙØ§ØªØ¬Ù (آجÙÙØ§ ÙØ§Ù ذÙ٠أÙ
عاجÙÙØ§)Ø Ø¨Ù Ø£Ù٠عÙÙÙ ÙØ¯Ø§Ø¡ ÙØ§ØØ¯Ùا Ù
Ù Ø±Ø¯ÙØ¯ اÙÙØ¯Ø§Ø¡ ÙØ°Ù:
resolve(value)â: ÙÙ Ø§ÙØªÙ ÙØª اÙÙ ÙÙ ÙØ© Ø¨ÙØ¬Ø§Ø. اÙÙÙÙ Ø© تسجÙÙ ÙÙvalue.reject(error)ââ ÙÙ ØØ¯Ø« خطأ.errorÙÙ ÙØ§Ø¦Ù Ø§ÙØ®Ø·Ø£. Ø¥Ø°ÙØ§ ÙÙÙØ®Ùص: ÙØ¹Ù ٠اÙÙ ÙÙÙÙÙØ° تÙÙØ§Ø¦ÙÙØ§ ÙØ¹ÙÙÙ Ù ÙÙ ÙØ© استدعاءresolveØ£Ùreject. ÙÙØ§Ø¦Ù اÙÙØ¹Ø¯promiseØ§ÙØ°Ù Ø£Ø¹Ø§Ø¯Ù Ø§ÙØ¨Ø§ÙÙnew PromiseØ®Ø§ØµÙØªÙ٠داخÙÙØªÙÙ:- Ø§ÙØØ§ÙØ©
state: تبدأ باÙÙÙÙ Ø©"pending"ÙØ¨Ø¹Ø¯Ùا ØªÙØªÙ٠إÙÙ"fulfilled"Ù ØªÙ Ø§Ø³ØªÙØ¯Ø¹ØªresolveØ Ø£Ù Ø¥ÙÙ&"rejected"Ù ØªÙ Ø§Ø³ØªÙØ¯Ø¹Øªreject. - اÙÙØ§ØªØ¬
result: ÙØ¨Ø¯Ø£ Ø£ÙÙÙØ§ ØºÙØ± ٠عرÙÙundefinedØ ÙØ¨Ø¹Ø¯Ùا ÙØªØºÙÙØ± Ø¥ÙÙvalueÙ ØªÙ Ø§Ø³ØªÙØ¯Ø¹Øªresolve(value)âØ£Ù ÙØªØºÙÙØ± Ø¥ÙÙerrorÙ ØªÙ Ø§Ø³ØªÙØ¯Ø¹Øªreject(error)â.
ÙÙ٠اÙÙÙØ§ÙØ© ÙÙÙ٠اÙÙ
ÙÙÙÙÙØ° اÙÙØ¹Ø¯Ù promise ÙÙØµÙر Ø¨Ø¥ØØ¯Ù Ø§ÙØØ§ÙØ§Øª Ø§ÙØ¢ØªÙØ©:
[promise-resolve-reject.png]
Ø³ÙØ±Ù ÙØ§ØÙÙØ§ ÙÙÙ Ø³ÙØ´ØªØ±Ù âÙ
ÙØ¹Ø¬Ø¨ÙÙØ§â Ø¨ÙØ°Ù Ø§ÙØªØºÙÙØ±Ø§Øª.
Ø¥ÙÙÙ Ù
ثاÙÙØ§ ع٠باÙÙÙØ§ ÙÙÙØ¹Ùد ÙØ¯Ø§ÙØ© Ù
ÙÙÙÙÙØ° Ø¨Ø³ÙØ·Ø© ÙÙÙØ§ âØ´ÙÙØ±Ø© Ù
ÙÙØªØ¬ÙØ©â ØªØ£Ø®Ø° بعض اÙÙÙØª (باستعÙ
ا٠setTimeout):
let promise = new Promise(function(resolve, reject) {
// تÙÙÙÙ Ø§ÙØ¯Ø§ÙØ© Ù
باشرة٠Ù
ا Ø¥Ù ÙÙØµÙع اÙÙØ¹Ø¯
// â«Ùبعد ثاÙÙØ© ÙØ§ØØ¯Ø© ÙØ¨Ø¹Ø« بإشارة بأÙ٠اÙÙ
ÙÙ
Ø© Ø§ÙØªÙت ÙØ§ÙÙØªÙجة ÙÙ âØªÙ
تâ (done)
setTimeout(() => resolve("done"), 1000);
});
بتشغÙÙ Ø§ÙØ´ÙÙØ±Ø© Ø£Ø¹ÙØ§ÙØ ÙØ±Ù أ٠رÙ٠اثÙÙÙ:
- ÙÙØ³ØªØ¯Ø¹Ù اÙÙ
ÙÙÙÙÙØ° تÙÙØ§Ø¦ÙÙØ§ ÙÙ
باشرة٠(Ø¹ÙØ¯ استعÙ
اÙ
new Promise). - ÙØ³ØªÙÙ
اÙÙ
ÙÙÙÙÙØ° ÙØ³ÙØ·ÙÙ: Ø¯Ø§ÙØ© Ø§ÙØÙÙ
resolveÙØ¯Ø§ÙØ© Ø§ÙØ±ÙضrejectØ ÙÙÙ Ø¯ÙØ§Ù ٠عرÙÙØ© ٠سبÙÙØ§ ÙÙ Ù ØØ±ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±ÙØ¨ØªØ ÙÙØ§ Ø¯Ø§Ø¹Ù Ø¨Ø£Ù ÙØµÙØ¹ÙØ§ ÙØÙØ ب٠استدعاء ÙØ§ØØ¯Ø© ٠ا Ø¥Ù ØªØ¬ÙØ² اÙÙØªÙجة. بعد Ø³ÙØ© ٠٠ع٠ÙÙØ© âØ§ÙÙ Ø¹Ø§ÙØ¬Ø©â ÙØ³ØªØ¯Ø¹Ù اÙÙ ÙÙÙÙÙØ° Ø§ÙØ¯Ø§ÙØ©Ùresolve("done")âÙØªÙÙØªØ¬ اÙÙØ§ØªØ¬. ÙÙØ°Ø§ تتغÙÙØ± ØØ§ÙØ© ÙØ§Ø¦Ùpromise: [promise-resolve-1.png] ÙØ§Ù ÙØ°Ø§ ٠ثاÙÙØ§ ع٠٠ÙÙ ÙØ© Ø§ÙØªÙ ÙØª Ø¨ÙØ¬Ø§ØØ Ø£Ù âÙØ¹Ø¯ تØÙÙÙâ. ÙØ§ÙØ¢Ù Ø³ÙØ±Ù ٠ثاÙÙØ§ ع٠٠ÙÙÙÙÙØ° ÙØ±Ùض اÙÙØ¹Ø¯ Ù ÙØ¹ÙØ¯ÙØ§ خطأÙ:
let promise = new Promise(function(resolve, reject) {
// بعد ثاÙÙØ© ÙØ§ØØ¯Ø© ÙØ¨Ø¹Ø« بإشارة بأÙ٠اÙÙ
ÙÙ
Ø© Ø§ÙØªÙت ÙÙÙØ¹Ùد خطأÙ
setTimeout(() => reject(new Error("Whoops!")), 1000);
});
باستدعاء reject(...)â ÙÙÙÙ ØØ§ÙØ© ÙØ§Ø¦Ù اÙÙØ¹Ø¯ Ø¥ÙÙ ØØ§ÙØ© Ø§ÙØ±Ùض "rejected":
[promise-reject-1.png]
Ù
ÙØ®Ùص اÙÙÙÙ Ù٠أÙ٠عÙ٠اÙÙ
ÙÙÙÙÙØ° تÙÙÙØ° اÙÙ
ÙÙ
Ø© (Ø£Ù Ù
ا ÙØ£Ø®Ø° بعض اÙÙÙØª ÙÙÙØªÙ
Ù) ÙØ«Ù
Ù ÙØ³ØªØ¯Ø¹Ù ÙØ§ØØ¯Ø©Ù Ù
Ù Ø§ÙØ¯Ø§ÙتÙÙ resolve Ø£Ù
reject ÙØªØºÙÙØ± ØØ§ÙØ© ÙØ§Ø¦Ù اÙÙØ¹Ø¯ اÙÙ
رتبط باÙÙ
ÙÙÙÙÙØ°.
ÙÙØ³Ù
Ù٠اÙÙØ¹Ø¯ Ø§ÙØ°Ù تØÙÙ٠أ٠ÙÙÙØ« اÙÙØ¹Ø¯ اÙÙ
ÙÙØ¬Ø²Ø عÙÙ Ø§ÙØ¹Ùس Ù
٠اÙÙØ¹Ø¯ اÙÙ
عÙÙÙ.
Ù
ÙØ§ØØ¸Ø©: Ø¥Ù
ا Ø£Ù ØªØ¸ÙØ± ÙØªÙجة ÙØ§ØØ¯Ø© Ø£Ù Ø®Ø·Ø£Ø ÙØ¬Ø¨ عÙ٠اÙÙ
ÙÙÙØ° Ø£Ù ÙØ³ØªØ¯Ø¹Ù Ø¥Ù
ا resolve Ø£Ù reject. أ٠تغÙÙØ± ÙÙ Ø§ÙØØ§ÙØ©
ÙØ¹Ø¯Ù تغÙÙØ±Ùا ÙÙØ§Ø¦ÙÙØ§.
ÙØ³ÙÙØªØ¬Ø§Ù٠جÙ
ÙØ¹ Ø§ÙØ§Ø³ØªØ¯Ø¹Ø§Ø¡Ø§Øª اÙÙØ§ØÙØ© Ø³ÙØ§Ø¡Ù Ø£ÙØ§Ùت resolve Ø£Ù reject:
let promise = new Promise(function(resolve, reject) {
resolve("done");
reject(new Error("â¦")); // ستتجاÙÙ
setTimeout(() => resolve("â¦")); // ستتجاÙÙ
});
اÙÙÙØ±Ø© ÙÙØ§ أ٠خرج عÙ
٠اÙÙ
ÙÙØ°Ù Ø³ÙØ¹Ø±Ø¶ Ø¥Ù
ا ÙØªÙجة Ù
عÙÙØ© أ٠خطأ.
ÙØªØªÙÙØ¹ Ø§ÙØªØ¹ÙÙÙ
تÙÙ resolve/reject ÙØ³ÙØ·ÙØ§ ÙØ§ØØ¯Ùا Ù
ÙØ±Ø±Ùا (أ٠بدÙÙ ÙØ³Ø·Ø§Ø¡ ÙÙØ§Ø¦ÙÙØ§) ÙØ£Ù ÙØ³Ø·Ø§Ø¡ إضاÙÙØ© Ø³ØªÙØªØ¬Ø§ÙÙ.
Ù
ÙØ§ØØ¸Ø©: Ø§ÙØ±Ùض Ù
ع ÙØ§Ø¦Ù Error
ÙÙ ØØ§Ù ØØ¯ÙØ« خطأ Ù
Ø§Ø ÙØ¬Ø¨ عÙ٠اÙÙ
ÙÙØ°Ù Ø£Ù ÙØ³ØªØ¯Ø¹Ù تعÙÙÙ
Ø© reject. ÙÙÙ
Ù٠تÙ
Ø±ÙØ± Ø£Ù ÙÙØ¹ Ù
٠اÙÙØ³Ø·Ø§Ø¡ (تÙ
اÙ
ÙØ§ Ù
Ø«Ù:
resolve). ÙÙÙÙ ÙÙØµÙ باستخداÙ
ÙØ§Ø¦Ùات Error (Ø£Ù Ø£Ù ÙØ§Ø¦Ùات ترث Ù
Ù Error). ÙÙØ±ÙØ¨ÙØ§ Ø³ÙØ¹Ø±Ù Ø¨ÙØ¶ÙØ Ø³Ø¨Ø¨ ذÙÙ.
Ù
ÙØ§ØØ¸Ø©: استدعاء resolve/reject اÙÙÙØ±Ù
عÙ
ÙÙÙØ§ عادة ÙÙØ¬Ø² اÙÙ
ÙÙØ°Ù عÙ
Ù٠بشÙÙ Ù
تزاÙ
Ù ÙÙØ³ØªØ¯Ø¹Ù resolve/reject بعد Ù
Ø±ÙØ± بعض اÙÙÙØªØ ÙÙÙÙ Ø§ÙØ£Ù
ر ÙÙØ³ Ø¥ÙØ²Ø§Ù
ÙÙØ§Ø
ÙÙ
ÙÙÙØ§ استدعاء resolve Ø£Ù reject ÙÙØ±ÙØ§Ø ÙÙØ°Ø§:
let promise = new Promise(function(resolve, reject) {
// ÙÙ
ÙÙÙØ§ اÙÙÙØ§Ù
باÙÙ
ÙÙ
Ø© Ù
باشرة
resolve(123); // Ø£Ø¸ÙØ± Ù
باشرة اÙÙØªÙجة: 123
});
عÙ٠سبÙ٠اÙÙ
ثا٠Ù
٠اÙÙ
Ù
ÙÙ Ø£Ù ÙØØ¯Ø« ذÙÙ ÙÙ ØØ§Ù Ø§ÙØ¨Ø¯Ø¡ بÙ
ÙÙ
Ø© Ù
عÙÙØ© ÙÙÙÙ ØªÙØªØ´Ù بأ٠ÙÙÙ Ø´ÙØ¡ Ø£ÙØ¬Ø² ÙØ®Ø²ÙÙ ÙÙ Ø§ÙØ°Ø§Ùرة اÙÙ
Ø¤ÙØªØ©.
ÙØ°Ø§ Ø¬ÙØ¯Ø ÙØ¹ÙØ¯ÙØ§ ÙØ¬Ø¨ Ø£Ù ÙÙØ¬Ø² اÙÙØ¹Ø¯ ÙÙØ±Ùا.
Ù
ÙØ§ØØ¸Ø©: Ø§ÙØØ§ÙØ© state ٠اÙÙØªÙجة result Ø§ÙØ¯Ø§Ø®ÙÙØªÙÙ
تÙÙ٠خصائص Ø§ÙØØ§ÙØ© state ٠اÙÙØªÙجة result ÙÙØ§Ø¦Ù اÙÙØ¹Ø¯ داخÙÙØ©. ÙÙØ§ ÙÙ
ÙÙÙØ§ اÙÙØµÙ٠إÙÙÙÙ
Ù
باشرة. ÙÙ
ÙÙÙØ§ استخداÙ
Ø§ÙØªÙØ§Ø¨ÙØ¹
â.then/.catch/.finally ÙØ°ÙÙ ÙØ§ÙØªÙ Ø³ÙØ´Ø±ØÙÙØ§ Ø£Ø¯ÙØ§Ù.
Ø§ÙØ§Ø³ØªÙÙØ§Ù: عبارات then Ùcatch Ùfinally
ÙØ§Ø¦Ù اÙÙØ¹Ø¯ ÙÙ ÙØ§ÙÙØµÙØ© بÙ٠اÙÙ
ÙÙÙÙÙØ° (Ø£Ù âØ§ÙØ´ÙÙØ±Ø© اÙÙ
ÙÙØªÙØ¬Ø©â Ø£Ù âØ§ÙÙ
غÙÙÙâ) ÙØ§ÙØ¯ÙØ§Ù اÙÙ
ÙØ³ØªÙÙÙØ© (Ø£Ù âØ§ÙÙ
ÙØ¹Ø¬Ø¨ÙÙâ) Ø§ÙØªÙ ستسÙÙ
اÙÙØ§ØªØ¬ Ø£Ù
Ø§ÙØ®Ø·Ø£. ÙÙ
Ù٠تسجÙÙ Ø¯ÙØ§Ù Ø§ÙØ§Ø³ØªÙÙØ§Ù (Ø£Ù Ø£Ù ØªØ´ØªØ±ÙØ ÙÙ
ا Ù٠اÙÙ
Ø«Ø§Ù Ø§ÙØ¹Ù
Ù٠ذاÙ) باستعÙ
Ø§Ù Ø§ÙØªÙØ§Ø¨ÙØ¹ â.then Ùâ.catch
Ùâ.finally.
then
ÙÙØ¹Ø¯Ù â.then Ø£ÙÙ
ÙÙØ§ ÙØ¹ÙÙ
اد اÙÙØµØ© ÙÙÙØ§. ØµÙØ§ØºØªÙ ÙÙ:
promise.then(
function(result) { /* ÙØªØ¹Ø§Ù
Ù Ù
ع اÙÙØ§ØªØ¬ Ø§ÙØµØÙØ */ },
function(error) { /* ÙØªØ¹Ø§Ù
Ù Ù
ع Ø§ÙØ®Ø·Ø£ */ }
);
اÙÙØ³ÙØ· Ø§ÙØ£ÙÙÙ Ù
Ù Ø§ÙØªØ§Ø¨Ùع â.then ÙÙØ¹Ø¯Ù Ø¯Ø§ÙØ© ØªÙØ´ØºÙ٠إ٠تØÙÙ٠اÙÙØ¹Ø¯Ø ÙÙÙÙ٠اÙÙØ³Ùط٠اÙÙØ§ØªØ¬.
بÙÙÙ
ا اÙÙØ³ÙØ· Ø§ÙØ«Ø§ÙÙ ÙÙØ¹Ø¯Ù Ø¯Ø§ÙØ©Ù ØªÙØ´ØºÙ٠إ٠رÙÙØ¶ اÙÙØ¹Ø¯Ø ÙÙÙÙ٠اÙÙØ³ÙØ·Ù Ø§ÙØ®Ø·Ø£.
Ø¥ÙÙÙ Ù
Ø«Ø§Ù ÙØªØ¹Ø§Ù
Ù ÙÙÙ Ù
ع ÙØ¹Ø¯ تØÙÙÙ Ø¨ÙØ¬Ø§Ø:
let promise = new Promise(function(resolve, reject) {
setTimeout(() => resolve("done"), 1000);
});
// â«ØªÙÙÙÙÙØ° resolve Ø£ÙÙ Ø¯Ø§ÙØ© ÙÙ â.then
promise.then(
result => alert(result), // shows "done" after 1 second
error => alert(error) // doesn't run
);
ÙÙØ°Ø§ ÙØ±Ù Ø§ÙØ¯Ø§ÙØ© Ø§ÙØ£ÙÙÙ ÙÙ Ø§ÙØªÙ ÙÙÙÙØ°Øª. ÙØ¥ÙÙ٠اÙ٠ثا٠ÙÙ ØØ§ÙØ© Ø§ÙØ±Ùض:
let promise = new Promise(function(resolve, reject) {
setTimeout(() => reject(new Error("Whoops")), 1000);
});
// â«ØªÙÙÙÙÙØ° reject ثاÙÙ Ø¯Ø§ÙØ© ÙÙ â.then
promise.then(
result => alert(result), // ÙØ§ تعÙ
Ù
error => alert(error) // â« Ø¥Ø¸ÙØ§Ø± "Error: Whoops!â" بعد ثاÙÙØ©
);
ÙÙ ÙÙ
ÙÙØ±Ùد Ø¥ÙÙØ§ ØØ§Ùات Ø§ÙØ§ÙØªÙØ§Ø¡ اÙÙØ§Ø¬ØØ©Ø ÙÙÙ
Ù٠أ٠ÙÙØ¯ÙÙ
Ø¯Ø§ÙØ©Ù ÙØ§ØØ¯Ø© ÙØ³ÙØ·ÙØ§ Ø¥ÙÙ â.then ÙÙØ·:
let promise = new Promise(resolve => {
setTimeout(() => resolve("done!"), 1000);
});
promise.then(alert); // â« Ø¥Ø¸ÙØ§Ø± "done!â" بعد ثاÙÙØ©
catch
ÙÙ ÙÙ
ÙÙÙ ÙÙØªÙ
٠إÙÙØ§ Ø¨Ø§ÙØ£Ø®Ø·Ø§Ø¡Ø ÙØ¹ÙÙÙØ§ استعÙ
ا٠null ÙØ³ÙØ·ÙØ§ Ø£ÙÙÙØ§: â.then(null, errorHandlingFunction)âØ Ø£Ù ÙØ³ØªØ¹Ù
Ù
â.catch(errorHandlingFunction)â ÙÙÙ ÙØ¤Ø¯Ù٠ذات اÙÙ
بدأ تÙ
اÙ
ÙØ§ ÙÙØ§ ÙØ±Ù Ø¥ÙÙØ§ ÙØµØ± Ø§ÙØ«Ø§ÙÙØ© Ù
ÙØ§Ø±ÙØ© Ø¨Ø§ÙØ£ÙÙÙ:
let promise = new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("Whoops!")), 1000);
});
// .catch(f) is the same as promise.then(null, f)
promise.catch(alert); // â«Ø¥Ø¸Ùار "Error: Whoops!â" بعد ثاÙÙØ©
finally
ÙÙ
ا اÙÙ
ÙÙØºÙÙÙØ© finally Ù٠عبارات try {...} catch {...}â Ø§ÙØ¹Ø§Ø¯ÙØ©Ø ÙÙÙØ§Ù Ù
Ø«ÙÙØ§ Ù٠اÙÙØ¹Ùد.
استدعاء â.finally(f)â ÙØ´Ø¨Ù استدعاء â.then(f, f)âØ ÙÙØ¬Ù Ø§ÙØ´Ø¨Ù Ù٠أÙÙ Ø§ÙØ¯Ø§ÙØ© f تعÙ
٠دÙÙ
ÙØ§ Ù
ت٠â¦. اÙÙØ¹Ø¯Ø ÙØ§Ù ÙØ¯ تØÙÙ٠أÙ
ÙÙÙØ«.
استعÙ
ا٠finally Ù
ÙÙØ¯ Ø¬Ø¯ÙØ§ ÙØªÙظÙÙ Ù
ا تبÙÙÙ Ù
٠أÙ
ÙØ± Ù
ÙÙ
ÙØ§ ÙØ§Ù ÙØ§ØªØ¬ اÙÙØ¹Ø¯Ø Ù
ث٠إÙÙØ§Ù Ø£ÙÙÙÙØ§Øª Ø§ÙØªØÙ
ÙÙ (ÙÙÙ
ÙØ¹Ø¯ ÙØØªØ§Ø¬ÙØ§). ÙÙØ°Ø§
Ù
Ø«ÙÙØ§:
new Promise((resolve, reject) => {
// â«Ø§ÙØ¹Ù Ø´ÙØ¦Ùا ÙØ³ØªØºØ±Ù ÙÙØªÙا Ø«Ù
استدع resolve/reject lre
})
// runs when the promise is settled, doesn't matter successfully or not
.finally(() => stop loading indicator)
.then(result => show result, err => show error)
ÙÙÙÙÙØ§ ÙÙØ³Øª Ù
ØªØ·Ø§Ø¨ÙØ© تÙ
اÙ
ÙØ§ Ù
ع then(f,f)âØ ÙÙÙØ§Ù ÙØ±ÙÙØ§Øª Ù
ÙÙ
ÙØ©:
- ÙÙØ³ ÙØ¯Ø§ÙØ© اÙÙ
ÙØ¹Ø§Ùجة
finallyØ£ÙÙ ÙØ³Ø·Ø§Ø¡. Ø£Ù ÙØ³Ùا ÙØ¹ÙÙ ÙÙfinallyØ£ÙØ§Ù اÙÙØ¹Ø¯ تØÙÙ٠أ٠ÙÙÙØ«Ø ÙÙØ°Ù ÙÙØ³Øª Ù Ø´ÙÙØ© إذ ٠ا ÙØ±Ùد٠عادة٠Ù٠تÙÙÙØ° بعض Ø§ÙØ£Ù ÙØ± âØ§ÙØ¹Ø§Ù ÙØ©â ÙÙÙÙÙ٠٠ا Ø¨Ø¯Ø£ÙØ§ بÙ. - ÙÙ
رÙÙ Ù
ÙØ¹Ø§Ùج
finallyعÙ٠اÙÙØªØ§Ø¦Ø¬ ÙØ§Ùأخطاء ÙØ¨Ø¹Ø¯Ùا Ø¥Ù٠اÙÙ Ø¹Ø§ÙØ¬ Ø§ÙØªØ§ÙÙ. ٠ثا٠عÙ٠ذÙÙ Ù٠اÙÙØ§ØªØ¬ Ø§ÙØ°Ù ØªÙ Ø±ÙØ± Ù ÙfinallyØ¥ÙÙthenÙÙØ§:
new Promise((resolve, reject) => {
setTimeout(() => resolve("result"), 2000)
})
// runs when the promise is settled, doesn't matter successfully or not
.finally(() => stop loading indicator)
// so the loading indicator is always stopped before we process the result/error
.then(result => show result, err => show error)
That said, finally(f) isnât exactly an alias of then(f,f) though. There are few subtle differences:
-
A
finallyhandler has no arguments. Infinallywe donât know whether the promise is successful or not. Thatâs all right, as our task is usually to perform âgeneralâ finalizing procedures. -
A
finallyhandler passes through results and errors to the next handler.For instance, here the result is passed through
finallytothen:new Promise((resolve, reject) => { setTimeout(() => resolve('result'), 2000); }) .finally(() => alert('Promise ready')) .then((result) => alert(result)); // <-- .then handles the resultAnd here thereâs an error in the promise, passed through
finallytocatch:new Promise((resolve, reject) => { throw new Error('error'); }) .finally(() => alert('Promise ready')) .catch((err) => alert(err)); // <-- .catch handles the error object
Thatâs very convenient, because finally is not meant to process a promise result. So it passes it through.
Weâll talk more about promise chaining and result-passing between handlers in the next chapter.
If a promise is pending, .then/catch/finally handlers wait for it. Otherwise, if a promise has already settled, they just run:
// the promise becomes resolved immediately upon creation
let promise = new Promise(resolve => resolve("done!"));
promise.then(alert); // done! (ØªØ¸ÙØ± Ø§ÙØ¢Ù)
Note that this makes promises more powerful than the real life âsubscription listâ scenario. If the singer has already released their song and then a person signs up on the subscription list, they probably wonât receive that song. Subscriptions in real life must be done prior to the event.
Promises are more flexible. We can add handlers any time: if the result is already there, they just execute.
Next, letâs see more practical examples of how promises can help us write asynchronous code.
Example: loadScript
Ø£Ù
اÙ
ÙØ§ Ù
٠اÙÙØµÙ اÙÙ
Ø§Ø¶Ù Ø§ÙØ¯Ø§ÙØ© loadScript ÙØªØÙ
ÙÙ Ø§ÙØ³Ùربتات.
Ø¥ÙÙÙ Ø§ÙØ¯Ø§ÙØ© بطرÙÙØ© Ø±Ø¯ÙØ¯ اÙÙØ¯Ø§Ø¡Ø ÙÙØªØ°ÙÙØ±Ùا ÙØ§ Ø£ÙØ«Ø± ÙÙØ§ Ø£ÙÙ:
function loadScript(src, callback) {
let script = document.createElement('script');
script.src = src;
script.onload = () => callback(null, script);
// خطأ Ù٠تØÙ
ÙÙ Ø§ÙØ³Ùربت ÙØ°Ø§
script.onerror = () => callback(new Error(`Script load error for ${src}`));
document.head.append(script);
}
ÙÙÙØ§ ÙÙØ¹Ø¯ ÙØªØ§Ø¨ØªÙا باستعÙ
ا٠اÙÙØ¹Ùد.
ÙÙ ØªØ·ÙØ¨ Ø¯Ø§ÙØ© loadScript Ø§ÙØ¬Ø¯Ùدة Ø£ÙÙ Ø±Ø¯ÙØ¯ ÙØ¯Ø§Ø¡Ø Ø¨Ù Ø³ØªØµÙØ¹ ÙØ§Ø¦Ù ÙØ¹Ø¯ ÙØªØÙÙÙ Ù
ØªÙ Ø§ÙØªÙ
Ù Ø§ÙØªØÙ
ÙÙØ ÙØªÙØ¹ÙØ¯Ù. ÙÙ
ÙÙ ÙÙØ´ÙÙØ±Ø©
Ø§ÙØ®Ø§Ø±Ø¬ÙØ© Ø¥Ø¶Ø§ÙØ© Ø§ÙØ¯Ùا٠اÙÙ
ÙØ¹Ø§Ùجة (Ø£Ù Ø¯ÙØ§Ù Ø§ÙØ§Ø´ØªØ±Ø§Ù) Ø¥ÙÙÙØ§ باستعÙ
ا٠.then:
function loadScript(src) {
return new Promise(function(resolve, reject) {
let script = document.createElement('script');
script.src = src;
script.onload = () => resolve(script);
script.onerror = () => reject(new Error(`Script load error for ${src}`));
document.head.append(script);
});
}
Ø§ÙØ§Ø³ØªØ¹Ù اÙ:
let promise = loadScript("https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js");
promise.then(
script => alert(`${script.src} is loaded!`),
error => alert(`Error: ${error.message}`)
);
promise.then(script => alert('Another handler...'));
Ø¨ÙØ¸Ø±Ø© Ø®Ø§Ø·ÙØ© ÙÙ ÙÙ Ø£Ù ÙØ±Ù ÙÙØ§Ø¦Ø¯ ÙØ°Ù Ø§ÙØ·Ø±ÙÙØ© Ù ÙØ§Ø²Ùة٠بطرÙÙØ© Ø±Ø¯ÙØ¯ اÙÙØ¯Ø§Ø¡:
| اÙÙØ¹Ùد | Ø±Ø¯ÙØ¯ اÙÙØ¯Ø§Ø¡ |
|---|---|
ØªØªÙØ ÙÙØ§ اÙÙØ¹Ùد تÙÙÙØ° Ø§ÙØ£Ù
ÙØ± Ø¨ØªØ±ØªÙØ¨Ùا Ø§ÙØ·Ø¨Ùع٠أÙÙÙØ§ ÙØ´ØºÙÙ loadScript(script)â ÙÙ
Ù Ø¨Ø¹Ø¯ÙØ§ â.then ÙÙØªØ¨ Ù
ا ÙØ±Ùد ÙØ¹ÙÙ |
|
| باÙÙØªÙجة. | ÙØ¬Ø¨ Ø£Ù ÙÙÙÙ ØªØ§Ø¨ÙØ¹ callback ØªØØª تصرÙÙØ§ Ø¹ÙØ¯ استدعاء loadScript(script, callback)â. بعبارة أخر٠|
ÙØ¬Ø¨ Ø£Ù ÙØ¹Ø±Ù Ù
ا سÙÙØ¹Ù٠باÙÙØªÙجة ÙØ¨Ù استدعاء loadScript. |
|
ÙÙ
ÙÙÙØ§ استدعاء â.then Ù٠اÙÙØ¹Ø¯ عدة Ù
رات ÙÙ
ا ÙØ±Ùد. ÙÙ ÙÙÙ Ù
رة ÙØ¶ÙÙ Ù
عجب Ø¬Ø¯ÙØ¯Ø© âfanâØ ÙÙØ§Ù٠تابع Ø³ÙØ¶ÙÙ Ù
شترÙÙÙ |
|
| Ø¬ÙØ¯Ø¯ Ø¥ÙÙ ÙØ§Ø¦Ù Ø© اÙ٠شترÙÙÙ. Ø³ÙØ±Ù اÙÙ Ø²ÙØ¯ ØÙÙ ÙØ°Ø§ Ø§ÙØ£Ù ر Ù٠اÙÙØµÙ اÙÙØ§Ø¯Ù :ââ | ÙÙ Ù٠أ٠ÙÙÙÙ ÙÙØ§ÙÙ Ø±Ø¯Ù ÙØ§ØØ¯ ÙÙØ·. |
Ø¥Ø°ÙØ§Ø ÙØ§ÙÙØ¹Ùد ØªÙØ¯ÙÙ ÙÙØ§ تØÙÙ ÙØ§ ٠رÙÙØ§ Ø¨Ø§ÙØ´ÙÙØ±Ø© ÙØ³Ùر تÙÙÙØ°ÙØ§Ø Ù٠ا Ø²Ø§ÙØª ÙÙØ§Ù٠اÙÙØ«Ùر Ù Ù Ø§ÙØ£Ù ÙØ± Ø§ÙØ±Ø§Ø¦Ø¹Ø© Ø§ÙØªÙ Ø³ÙØªØ¹Ø±Ù عÙÙÙØ§ اÙÙØµÙ اÙÙØ§Ø¯Ù .
ت٠ارÙÙ
إعادة ⦠اÙÙØ¹Ø¯Ø
٠ا ÙØ§ØªØ¬ Ø§ÙØ´ÙÙØ±Ø© Ø£Ø¯ÙØ§ÙØ
let promise = new Promise(function(resolve, reject) {
resolve(1);
setTimeout(() => resolve(2), 1000);
});
promise.then(alert);
Ø§ÙØÙ
اÙÙØ§ØªØ¬ ÙÙ: 1.
ÙÙÙÙ
٠استدعاء resolve Ø§ÙØ«Ø§Ù٠إذ ÙØ§ ÙØªÙÙ
٠اÙÙ
ØØ±Ù٠إÙÙØ§ بأÙ٠استدعاء Ù
Ù reject/resolveØ ÙØ§ÙباÙÙ ÙÙÙÙ ÙÙÙÙ
Ù.
Ø§ÙØªØ£Ø®Ùر باستع٠ا٠اÙÙØ¹Ùد
تستعÙ
Ù Ø§ÙØ¯Ø§ÙØ© اÙÙ
ضÙ
ÙÙØ© Ù٠اÙÙØºØ© setTimeout Ø±Ø¯ÙØ¯Ù اÙÙØ¯Ø§Ø¡. Ø§ØµÙØ¹ ÙØ§ØØ¯Ø© تستعÙ
٠اÙÙØ¹Ùد.
عÙÙ Ø§ÙØ¯Ø§ÙØ© delay(ms)â Ø¥Ø¹Ø§Ø¯Ø© ÙØ¹Ø¯ ÙÙØ¬Ø¨ Ø£Ù â¦ ÙØ°Ø§ اÙÙØ¹Ø¯ Ø®ÙØ§Ù ms Ù
ÙÙØ«Ø§ÙÙØ©Ø ÙÙÙØ¶ÙÙ ØªØ§Ø¨ÙØ¹ .then Ø¥ÙÙÙ ÙÙØ°Ø§:
function delay(ms) {
// Ø´ÙÙØ±ØªÙ ÙÙØ§
}
delay(3000).then(() => alert('runs after 3 seconds'));
Ø§ÙØÙ
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
delay(3000).then(() => alert('runs after 3 seconds'));
ÙØ§ØØ¸ Ø£ÙÙÙØ§ ÙÙ ÙØ°Ø§ Ø§ÙØªÙ
رÙ٠استدعÙÙØ§ resolve Ø¨ÙØ§ ÙØ³Ø·Ø§Ø¡Ø ÙÙÙ
ÙÙØ¹Ø¯ Ø£ÙÙ ÙÙÙ
Ø© Ù
Ù delay ب٠⦠ÙÙØ·
ØµÙØ±Ø© دائرة Ù ØªØØ±ÙØ© ٠ع ÙØ¹Ø¯
Ø£Ø¹ÙØ¯ ÙØªØ§Ø¨Ø© Ø§ÙØ¯Ø§ÙØ© showCircle ÙÙ ØÙÙ Ø§ÙØªÙ
رÙÙ
[Ø§ÙØ³Ø§Ø¨Ù](https://academy.hsoub.com/programming/javascript/%D9%85%D9%82%D8%AF%D9
%85%D8%A9-%D8%A5%D9%84%D9%89-%D8%B1%D8%AF%D9%88%D8%AF-
%D8%A7%D9%84%D9%86%D8%AF%D8%A7%D8%A1-callbacks-%D9%81%D9%8A-
%D8%AC%D8%A7%D9%81%D8%A7%D8%B3%D9%83%D8%B1%D8%A8%D8%AA-
r914/) ÙØªÙØ¹ÙØ¯ ÙØ¹Ø¯Ùا بد٠أ٠تستÙÙ
Ø±Ø¯Ù ÙØ¯Ø§Ø¡. ÙÙÙÙ٠استعÙ
اÙÙØ§ Ø§ÙØ¬Ø¯Ùد ÙÙØ°Ø§:
showCircle(150, 150, 100).then(div => {
div.classList.add('message-ball');
div.append("Hello, world!");
});
ÙÙÙÙ Ø§ÙØÙÙ ÙÙ Ø§ÙØªÙ رÙ٠اÙ٠ذÙÙØ± أساس اÙÙ Ø³Ø£ÙØ© Ø§ÙØ¢Ù.
Ø§ÙØÙ
ÙÙ ÙÙÙ Ù Ø´Ø§ÙØ¯Ø© Ø§ÙØÙ Ø¹Ø¨Ø± اÙÙ Ø«Ø§Ù Ø§ÙØÙ. ترج٠ة -ÙØ¨ØªØµØ±Ù- ÙÙÙØµÙ Promise Ù Ù ÙØªØ§Ø¨ The JavaScript language
Ø§ÙØªØ¹ÙÙÙØ§Øª
<code>Ø ÙÙÙÙØ«Ùر Ù Ù Ø§ÙØ³Ø·Ùر استخدÙ<pre>Ø ÙÙØ£Ùثر Ù Ù 10 Ø³Ø·ÙØ± استخد٠(plnkr, JSBin, codepenâ¦)