قبل أن نبدأ المقدمة الرسمية ، نريد أن نرى شكل وعد JavaScript:
نسخة الكود كما يلي:
var p = وعد جديد (وظيفة (حل ، رفض) {
حل ("Hello World") ؛
}) ؛
P.Then (وظيفة (str) {
تنبيه (STR) ؛
}) ؛
1. ثم () يعيد وعد متشعب
ما هو الفرق بين الرموبين التاليين؟
نسخة الكود كما يلي:
// معرض أ
var p = وعد جديد (/*...*/) ؛
P.Then (FUNC1) ؛
P.Then (func2) ؛
// معرض ب
var p = وعد جديد (/*...*/) ؛
P.Then (FUNC1)
. ثم (func2) ؛
إذا كنت تفكر بعناية في قطعتي الكود المذكورة أعلاه ، فإن الوعود هي مجرد مجموعة أحادية البعد من وظائف رد الاتصال. ومع ذلك ، هذا ليس هو الحال. كل ثم استدعاء يعيد وعد متشعب. لذلك ، في العرض ، إذا كان FUNC1 () يلقي استثناءً ، فلا يزال يسمى FUNC2 () بشكل طبيعي.
في المعرض ، إذا قام FUNC1 () بإلقاء خطأ ، فلن يتم استدعاء Fun2 () لأن المكالمة الأولى تعيد وعدًا جديدًا ، سيتم رفضه في FUNC1 (). والنتيجة هي func2 () التي يتم تخطيها.
ملخص: يمكن أن تكون الوعود مفترقة في مسارات متعددة ، على غرار المخططات الانسيابية المعقدة.
2. يجب أن يمر رد الاتصال بالنتيجة
ماذا سيحصل على تحذير عند تشغيل الرمز التالي؟
نسخة الكود كما يلي:
var p = وعد جديد (وظيفة (حل ، رفض) {
حل ("Hello World") ؛
}) ؛
P.Then (وظيفة (str) {})
.Then (وظيفة (str) {
تنبيه (STR) ؛
}) ؛
التنبيه في الثانية ثم () لا يظهر أي شيء. وذلك لأن وظيفة رد الاتصال ، في سياق الوعد ، لا توجد وظيفة رد اتصال لأن النتيجة تتغير. يتوقع Promise أن يعيد رد الاتصال الخاص بك بنفس النتيجة أو نتيجة بديلة ، والتي يتم تمريرها بعد ذلك إلى رد الاتصال التالي.
على غرار استخدام Adpater لتغيير النتائج ، على النحو التالي:
نسخة الكود كما يلي:
var feettometres = function (ft) {return ft*12*0.0254} ؛
var p = وعد جديد (/*...*/) ؛
P.Then (Feettometres)
.Then (وظيفة (متر) {
تنبيه (متر) ؛
}) ؛
3. يمكن اكتشاف استثناءات فقط من الطبقة السابقة
ما هو الفرق بين هاتين القطعتين من الكود؟
نسخة الكود كما يلي:
// معرض أ
وعد جديد (وظيفة (حل ، رفض) {
حل ("Hello World") ؛
})
.ثم(
وظيفة (str) {
رمي خطأ جديد ("أه أوه") ؛
} ،
غير محدد
)
.ثم(
غير محدد ،
دالة (خطأ) {
تنبيه (خطأ) ؛
}
) ؛
// معرض ب
وعد جديد (وظيفة (حل ، رفض) {
حل ("Hello World") ؛
})
.ثم(
وظيفة (str) {
رمي خطأ جديد ("أه أوه") ؛
} ،
دالة (خطأ) {
تنبيه (خطأ) ؛
}
) ؛
في الجزء الأول من التعليمات البرمجية ، يتم إلقاء الاستثناء في الأول ثم () وسيتم القبض عليه من قبل الثانية () ، وسيتم تحذير "Uh OH". سيتم اكتشاف هذا الدليل فقط على المستوى السابق.
في الجزء الثاني من التعليمات البرمجية ، تكون وظيفة رد الاتصال ووظيفة رد الاتصال في نفس المستوى ، مما يعني أنه عندما يتم إلقاء استثناء في رد الاتصال ، فلن يتم اكتشافه. في الواقع ، لن يتم إلقاء رد فعل الخطأ في الكود الثاني إلا إذا تم رفض الوعد أو إذا كان الوعد نفسه خطأ.
4. يمكن استعادة الأخطاء
في وظيفة رد الاتصال على خطأ ، إذا لم تقم بإعادة تقديم الخطأ ، فإن الوعد يفترض أنك استعادت من الخطأ وعقلت إلى حالة تم حلها. في المثال التالي ، سيتم عرض "أنا محفوظ" لأن رد اتصال الخطأ في الأول () لم يعيد إدخال الاستثناء.
نسخة الكود كما يلي:
var p = وعد جديد (وظيفة (حل ، رفض) {
رفض (خطأ جديد ("pebkac")) ؛
}) ؛
P.Then (
غير محدد ،
دالة (خطأ) {}
)
.ثم(
وظيفة (str) {
تنبيه ("أنا أنقذ!") ؛
} ،
دالة (خطأ) {
تنبيه ("الكمبيوتر السيئ!") ؛
}
) ؛
يمكن اعتبار الوعد طبقة على البصل. كل ثم () يضيف مستوى آخر إلى البصل. يمثل كل مستوى نشاطًا معالجًا. عند الانتهاء من التسلسل الهرمي ، تعتبر النتيجة ثابتة وجاهزة للتسلسل الهرمي التالي.
5. يمكن تعليق الوعود
نظرًا لأنك مستعد للتنفيذ بطريقة واحدة () ، فهذا لا يعني أنه لا يمكنك التوقف وتشغيله مسبقًا. من أجل إيقاف الوعد الحالي ، أو اتركه ينتظر إكمال وعد آخر ، ما عليك سوى إرجاع وعد آخر في ثم ().
نسخة الكود كما يلي:
var p = وعد جديد (/*...*/) ؛
P.Then (وظيفة (str) {
إذا (! loggedin) {
إرجاع وعد جديد (/*...*/) ؛
}
})
.Then (وظيفة (str) {
تنبيه ("تم.") ؛
})
في الكود السابق ، لن يظهر المطالبة حتى يتم تحليل الوعد الجديد. هذه طريقة مريحة لإدخال المزيد من التبعيات في مسار الكود غير المتزامن الحالي. على سبيل المثال ، قد تجد أن جلسة المستخدم لديها مهلة وقد ترغب في تهيئة تسجيل الدخول الثاني قبل المتابعة مع مسار الكود السابق.
6. لن يتم تنفيذ الوعود التي تم حلها على الفور
هل ستحصل على مربع موجه عند تشغيل الرمز التالي؟
نسخة الكود كما يلي:
وظيفة RunMe () {
var i = 0 ؛
وعد جديد (وظيفة (حل) {
حل()؛
})
.Then (function () {
i += 2 ؛
}) ؛
تنبيه (ط) ؛
}
نظرًا لأنه يتم تحليل الوعد على الفور ثم يتم تنفيذ طريقة () على الفور ، فقد تعتقد أنه سيتم التحقيق في المطالبة 2. ومع ذلك ، يتطلب تعريف الوعد إجبار جميع المكالمات على عدم التزامن. لذلك ، سيتم إنشاء المطالبة قبل تعديلها.