Async: لا يحمي Async من تعديلات الصفيف أثناء وقت تشغيل الوظيفة

تم إنشاؤها على ٤ يوليو ٢٠١٤  ·  6تعليقات  ·  مصدر: caolan/async

عندما يكون لديك مكالمة غير متزامنة على سبيل المثال. 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 والذي يمكن أن يتغير ... أليس من الأفضل تخزين طول المصفوفة الأصلي وإجراء مقارنة مع ذلك ، مما يضمن استدعاء رد الاتصال المكتمل ؟

كمان:
http://jsfiddle.net/4ysKX/1/

bug

التعليق الأكثر فائدة

هل انتهى الأمر بعدم التزامن بعدم السماح بتعديلات المصفوفة بعد وقوعها؟ لدي حالة استخدام حيث سيكون من الجيد تعديل المصفوفة الأصلية بعد الحقيقة ، وذلك للتكرار على عناصر أكثر من البداية.

ال 6 كومينتر

أنت على حق - لذا لا تقم بتعديله. قم باستنساخ المصفوفة الخاصة بك قبل تمريرها إلى وظيفة غير متزامنة إذا كنت بحاجة إلى تغييرها لاحقًا.

aearly نعم ، هذا

سيكون من الصعب الحماية من أي تعديل في المصفوفة دون استنساخ المدخلات ، على سبيل المثال تعديل متزامن في وظيفة التكرار ، ولكن الحماية ضد التعديل غير المتزامن غير المتزامن مع التكرار يجب أن يكون مباشرًا حتى بدون استنساخ - حقًا لا تفترض arr.length سيبقى

(أعمل مع bradens - سيقدم أحدنا PR مع اختبارات إذا كان ذلك موضع ترحيب).

ستكون العلاقات العامة مع الاختبارات موضع ترحيب ، لكن الأمر متروك في النهاية إلى caolan لدمجها.

الجانب السلبي للقيام بذلك هو الحمل الزائد لنسخ الصفيف. إذا كان لديك مصفوفة كبيرة ، أو تستدعي async.each et al عدة مرات ، فسيكون أبطأ وسيستخدم المزيد من الذاكرة.

أوافق على أن نسخة المصفوفة ستكون أكثر من اللازم. أقترح أنه نظرًا لأن التكرار الأولي للمصفوفة متزامن ، يمكن حفظ طول المصفوفة الأصلي للتحقق منه لاحقًا. بهذه الطريقة ، سيتطابق عدد مكالمات رد الاتصال مع عدد مكالمات المكرر ، حتى إذا تم تغيير المصفوفة في هذه الأثناء. يجب أن يكون هذا سهلاً وبدون أي نفقات إضافية مقابل async.each ، لكنني لم ألقي نظرة على الوظائف الأخرى بعد. سيكون من الجيد لو كانت جميع الوظائف المتوازية لديها سلوك ثابت في هذه الحالات.

هذه نسخة مكررة من # 557.

هل انتهى الأمر بعدم التزامن بعدم السماح بتعديلات المصفوفة بعد وقوعها؟ لدي حالة استخدام حيث سيكون من الجيد تعديل المصفوفة الأصلية بعد الحقيقة ، وذلك للتكرار على عناصر أكثر من البداية.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات