عندما يكون لديك مكالمة غير متزامنة على سبيل المثال. async.each
، وخلال وقت التشغيل هذا ، المصفوفة التي يتم تمريرها بها تعديلات عليها ، فقد لا تنتهي أبدًا ، أو ستستدعي رد الاتصال مرتين.
مثال:
async = require "async"
arr = [1, 2, 3]
async.each arr, ((i, cb) -> console.log "i"; setImmediate(cb)), (err) -> console.log "done"
arr.push(4)
يتكرر هذا المثال عبر عناصر المصفوفة الأصلية الثلاثة ، ويطبع i
ولكن بعد ذلك لا يستدعي رد الاتصال أبدًا ، لأنه في async.each
يقوم بما يلي:
if (completed >= arr.length) {
callback(null);
}
عند النظر إلى الكود غير المتزامن ، فإنه يقوم بإجراء مقارنة مع arr.length
والذي يمكن أن يتغير ... أليس من الأفضل تخزين طول المصفوفة الأصلي وإجراء مقارنة مع ذلك ، مما يضمن استدعاء رد الاتصال المكتمل ؟
أنت على حق - لذا لا تقم بتعديله. قم باستنساخ المصفوفة الخاصة بك قبل تمريرها إلى وظيفة غير متزامنة إذا كنت بحاجة إلى تغييرها لاحقًا.
aearly نعم ، هذا
سيكون من الصعب الحماية من أي تعديل في المصفوفة دون استنساخ المدخلات ، على سبيل المثال تعديل متزامن في وظيفة التكرار ، ولكن الحماية ضد التعديل غير المتزامن غير المتزامن مع التكرار يجب أن يكون مباشرًا حتى بدون استنساخ - حقًا لا تفترض arr.length
سيبقى
(أعمل مع bradens - سيقدم أحدنا PR مع اختبارات إذا كان ذلك موضع ترحيب).
ستكون العلاقات العامة مع الاختبارات موضع ترحيب ، لكن الأمر متروك في النهاية إلى caolan لدمجها.
الجانب السلبي للقيام بذلك هو الحمل الزائد لنسخ الصفيف. إذا كان لديك مصفوفة كبيرة ، أو تستدعي async.each
et al عدة مرات ، فسيكون أبطأ وسيستخدم المزيد من الذاكرة.
أوافق على أن نسخة المصفوفة ستكون أكثر من اللازم. أقترح أنه نظرًا لأن التكرار الأولي للمصفوفة متزامن ، يمكن حفظ طول المصفوفة الأصلي للتحقق منه لاحقًا. بهذه الطريقة ، سيتطابق عدد مكالمات رد الاتصال مع عدد مكالمات المكرر ، حتى إذا تم تغيير المصفوفة في هذه الأثناء. يجب أن يكون هذا سهلاً وبدون أي نفقات إضافية مقابل async.each
، لكنني لم ألقي نظرة على الوظائف الأخرى بعد. سيكون من الجيد لو كانت جميع الوظائف المتوازية لديها سلوك ثابت في هذه الحالات.
هذه نسخة مكررة من # 557.
هل انتهى الأمر بعدم التزامن بعدم السماح بتعديلات المصفوفة بعد وقوعها؟ لدي حالة استخدام حيث سيكون من الجيد تعديل المصفوفة الأصلية بعد الحقيقة ، وذلك للتكرار على عناصر أكثر من البداية.
التعليق الأكثر فائدة
هل انتهى الأمر بعدم التزامن بعدم السماح بتعديلات المصفوفة بعد وقوعها؟ لدي حالة استخدام حيث سيكون من الجيد تعديل المصفوفة الأصلية بعد الحقيقة ، وذلك للتكرار على عناصر أكثر من البداية.