كيف تختلف العقود المستقبلية والوعود Clojure؟
-
30-09-2019 - |
سؤال
كلا من العقود الآجلة والوعود تمنع حتى يحسبوا قيمها ، فما الفرق بينهما؟
المحلول
الرد على شروط clojure ، إليك بعض الأمثلة من Sean Devlin's Screencast:
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
لاحظ أنه في الوعد ، تقوم بتقديم قيمة صريحة تحددها في حساب لاحق (:fred
في هذه الحالة). المستقبل ، من ناحية أخرى ، يتم استهلاكه في نفس المكان الذي تم إنشاؤه. ال some-expr
من المفترض أن يتم إطلاقه خلف الكواليس ويتم حسابه بشكل جنب (في النهاية) ، ولكن إذا ظل لا يقيس بحلول الوقت الذي يتم فيه الوصول إلى كتل الخيوط حتى تتوفر.
تم تحريره لإضافة
للمساعدة في التمييز بين الوعد والمستقبل ، لاحظ ما يلي:
يعد
- يمكنك إنشاء
promise
. يمكن الآن تمرير كائن الوعد إلى أي موضوع. - يمكنك متابعة الحسابات. يمكن أن تكون هذه حسابات معقدة للغاية تتضمن الآثار الجانبية ، وتنزيل البيانات ، وإدخال المستخدم ، والوصول إلى قاعدة البيانات ، والوعود الأخرى-مهما تريد. سيبدو الرمز إلى حد كبير مثل رمز الخط الرئيسي في أي برنامج.
- عندما تنتهي ، يمكنك
deliver
نتائج هذا الكائن الوعد. - أي عنصر يحاول
deref
وعدك قبل الانتهاء من حسابك سيتم حظره حتى تنتهي. بمجرد الانتهاء وأنتdeliver
إد الوعد ، الوعد لن يحظر بعد الآن.
مستقبل
- أنت تخلق مستقبلك. جزء من مستقبلك هو تعبير عن الحساب.
- قد يتم تنفيذ المستقبل أو لا ينفذ بشكل متزامن. يمكن تعيين خيط ، ربما من تجمع. يمكن أن تنتظر فقط ولا تفعل شيئًا. من وجهة نظرك لا يمكنك ان تخبر.
- في مرحلة ما أنت (أو موضوع آخر)
deref
ق المستقبل. إذا اكتمل الحساب بالفعل ، فستحصل على نتائج منه. إذا لم تكتمل بالفعل ، فأنت تمنع حتى يكون ذلك. (من المفترض أنه لم يبدأ بعد ،deref
وهذا يعني أنه يبدأ في التنفيذ ، لكن هذا أيضًا غير مضمون.)
بينما أنت استطاع اجعل التعبير في المستقبل معقدًا مثل الكود الذي يتبع إنشاء وعد ، من المشكوك فيه أنه أمر مرغوب فيه. هذا يعني أن العقود الآجلة أكثر ملاءمة حقًا للحسابات السريعة والقدرة على الخلفية في حين أن الوعود أكثر ملاءمة حقًا لمسارات التنفيذ الكبيرة والمعقدة. أيضًا ، تبدو الوعود ، من حيث الحسابات المتاحة ، أكثر مرونة وتوجه نحو منشئ الوعد الذي يقوم بالعمل وخيط آخر يجني الحصاد. يتم توجيه العقود المستقبلية نحو بدء تشغيل مؤشر ترابط تلقائيًا (بدون النفقات العامة القبيحة والمعرضة للخطأ) والاستمرار مع أشياء أخرى حتى تحتاج إلى النتائج.
نصائح أخرى
كل من المستقبل والوعد آليات لتوصيل نتيجة غير متزامنة حساب من المنتج إلى المستهلك (المستهلكين).
في حالة مستقبل ال حساب يتم تعريفه في وقت الخلق المستقبلي وتنفيذ Async يبدأ "في أسرع وقت ممكن". كما أنه "يعرف" كيفية تفرخ حساب غير متزامن.
في حالة يعد ال حساب, ، انها وقت البدء و [ممكن الاحتجاج غير المتزامن يتم فصلها عن آلية التسليم. متي حساب النتيجة متاحة يجب الاتصال بالمنتج deliver
بشكل صريح ، مما يعني أيضًا أن المنتج يتحكم متى تصبح النتيجة متاحة.
إلى عن على وعود يرتكب Clojure خطأ في التصميم باستخدام نفس الكائن (نتيجة promise
استدعاء) لكلا الإنتاج (deliver
) وتستهلك (deref
) نتائج حساب. هاتان قدرتان متميزتان للغاية ويجب معاملتهما على هذا النحو.
هناك بالفعل إجابات ممتازة ، لذا فإن إضافة ملخص "كيفية استخدام" فقط:
كلاهما
خلق الوعد أو المستقبل يعيد إشارة على الفور. هذه الكتل المرجعية على @/deref حتى يتم توفير نتيجة للحساب بواسطة مؤشر ترابط آخر.
مستقبل
عند إنشاء المستقبل ، يمكنك تقديم وظيفة متزامنة. يتم تنفيذه في موضوع من تجمع غير محدود.
يعد
لا تعطي أي حجج عند خلق الوعد. يجب تمرير المرجع إلى مؤشر ترابط "المستخدم" الآخر الذي سوف deliver
النتائج.
أولا ، أ Promise
هو Future
. أعتقد أنك تريد أن تعرف الفرق بين أ Promise
و FutureTask
.
أ Future
يمثل قيمة غير معروفة حاليًا ولكنها ستعرف في المستقبل.
أ FutureTask
يمثل نتيجة حساب سيحدث في المستقبل (ربما في بعض تجمعات الخيوط). عندما تحاول الوصول إلى النتيجة ، إذا لم يحدث الحساب بعد ، فإنه يحظر. وإلا يتم إرجاع النتيجة على الفور. لا يوجد أي طرف آخر متورط في الحوسبة النتيجة حيث يتم تحديد الحساب مقدمًا مقدمًا.
أ Promise
يمثل نتيجة سيتم تسليمها من قبل بروميزر إلى العدالة في المستقبل. في هذه الحالة ، فأنت العذبة و Promiser هو أن الشخص الذي أعطاك Promise
هدف. مشابهه ل FutureTask
, ، إذا حاولت الوصول إلى النتيجة قبل Promise
لقد تم الوفاء به ، يتم حظره حتى يحقق بروميزر Promise
. مرة واحدة في Promise
يتم الوفاء به ، تحصل على نفس القيمة دائمًا وعلى الفور. على عكس أ FutureTask
, ، هناك حزب آخر متورط هنا ، أحدهم صنع Promise
. أن طرف آخر مسؤول عن القيام بالحساب والوفاء Promise
.
بهذا المعنى ، أ FutureTask
هو Promise
لقد صنعت لنفسك.