
في الاجتماع الحادي والسبعين لـ Ecma TC39 ، سيتم النظر في المشروع والتنفيذ المرجعي لـ Promise.allSettled
، وهو ثالث من Promise.allSettled
الرئيسيين الأربعة للوعود.
المؤلفون : جيسون ويليامز (بي بي سي) ، روبرت بوملي (بلومبرج) ، ماتياس بينينس (جوجل)
بطل المسابقة: ماتياس بينينس (Google)
المرحلة : 3
لمحبي دبليو ، مكررة على يوتيوب .
مقدمة والدافع
هناك أربعة أدوات دمج رئيسية في عالم الوعود:
Promise.all
. ES2015. يتم إغلاقه عند الوعد الأول المرفوض / المرفوض.Promise.race
. ES2015. يغلق في أول وعد حل / تسوية بطريقة أو بأخرى.Promise.any
. المرحلة 1. يغلق في أول وعد بالرضا / الوفاء.Promise.allSettled
. المرحلة 3 → المرحلة 4. لا تغلق.
يتم تمثيل كل منهم على نطاق واسع في مكتبات المستخدم العادية ، كل منها مفيد في حد ذاته ومناسب في حالات مختلفة.
يحدث التطبيق الرئيسي لهذا المركب عندما تريد تنفيذ إجراء فور الانتهاء من العديد من الطلبات ، بغض النظر عما إذا كانت قد انتهت بالنجاح أم الفشل. يتم إغلاق بقية أدوات دمج الوعود ( ماس كهربائى ) ، متجاهلة نتائج قيم المدخلات التي فقدت السباق لحالة معينة من النظام. تعد Promise.allSettled
فريدة من نوعها من حيث أنها تتوقع دائمًا من هو المسؤول عنها.
Promise.allSettled
بإرجاع الوعد ، الذي يتم تنفيذه مع إرجاع مجموعة من اللقطات Promise.allSettled
الوعود ، ولكن فقط بعد حل جميع الوعود الأصلية تمامًا.
أين اسم allSettled يأتي من؟
نقول إن الوعد يتم تسويته (يتم تسويته ) إذا لم يتم تعليقه معلقًا ، أي عندما يكون راضيًا أو مرفوضًا - أحد أمرين. لفهم المصطلحات ، ألقِ نظرة على وثيقة الدول القديمة والمصائر .
وأيضًا ، allSettled
هذا الاسم ، allSettled
، على نطاق واسع في المكتبات الحالية التي تنفذ هذه الوظيفة. القائمة ستكون أدناه.
أمثلة
تخيل أنك بحاجة إلى التكرار على مجموعة من الوعود وإرجاع قيمة جديدة ذات وضع معروف (والذي يحدث في أي من الفرعين الممكنين للمنطق).
function reflect(promise) { return promise.then( (v) => { return { status: 'fulfilled', value: v }; }, (error) => { return { status: 'rejected', reason: error }; } ); } const promises = [ fetch('index.html'), fetch('https://does-not-exist/') ]; const results = await Promise.all(promises.map(reflect)); const successfulPromises = results.filter(p => p.status === 'fulfilled');
تسمح واجهة برمجة التطبيقات المقترحة للمطور بمعالجة هذه الخيارات ، دون الحاجة إلى إنشاء وظيفة reflect
بشكل مستقل ، أو تخزين النتائج في متغيرات مؤقتة. واجهة برمجة التطبيقات الجديدة تبدو كما يلي:
const promises = [ fetch('index.html'), fetch('https://does-not-exist/') ]; const results = await Promise.allSettled(promises); const successfulPromises = results.filter(p => p.status === 'fulfilled');
إذا كنا بحاجة لوعود مرفوضة لسبب ما ، فربما نحتاج إلى جمع أسباب ما حدث. allSettled
يجعل هذا بنفس السهولة.
const promises = [ fetch('index.html'), fetch('https://does-not-exist/') ]; const results = await Promise.allSettled(promises); const errors = results .filter(p => p.status === 'rejected') .map(p => p.reason);
أمثلة حقيقية
من الأمور الشائعة تمامًا الرغبة في معرفة أن جميع الطلبات قد استكملت ، بغض النظر عن حالة كل منها. هذا مهم عندما تريد القيام بتحسين تدريجي في المستقبل. لا نحتاج دائمًا إلى الحصول على استجابة من واجهة برمجة التطبيقات.
const urls = [ ]; const requests = urls.map(x => fetch(x));
باستخدام Promise.allSettled
يمكنك كتابة شيء أكثر انسجاما مع توقعاتنا.
تطبيقات مخصصة
بلغات أخرى
توجد وظائف مماثلة في لغات أخرى ، تحت أسماء مختلفة. نظرًا لعدم وجود آلية عالمية متوافقة فورًا مع العديد من اللغات ، يتبع هذا المستند مثال الأسماء من المكتبات المذكورة أعلاه. إليك كيف تبدو بلغات أخرى:
- الصدأ -
futures::join
؛ - C # -
Task.WhenAll
. يمكنك استخدام try / catch أو TaskContinuationOptions.OnlyOnFaulted
؛ - Python -
asyncio.wait
مع خيار ALL_COMPLETED
- جافا -
CompletableFuture.allOf
مواد لمزيد من الدراسة
دقائق من اجتماعات TC39
مواصفة
تطبيق