Async: طريقة لتحديد العناصر غير المجهزة من خريطة غير متزامنة () بعد انبعاث الخطأ

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

أهلا،

أثناء استخدام الخريطة (...) ، هل هناك طريقة عند معالجة خطأ صادر من وظيفة التكرار لتحديد عدد العناصر التي لم تتم معالجتها بعد من المجموعة المتوفرة؟

أنا أستخدم map لتنفيذ عدة طلبات HTTP صادرة (باستخدام العقدة مكتبة request ) لمجموعة من عناوين urlsparams المختلفة ، وما إلى ذلك. جزئيًا من خلال إجراء أي من هذه الطلبات قد أحصل على خطأ معين من الملقم الهدف الذي أنا يمكن التعامل معها، ولكنني بعد ذلك تريد إعادة عملية يجري العمل العنصر الحالي على وثم أي المتبقية منها أن map لم تحدد بعد حتى.

لقد تساءلت عن إمكانية وضع علامة على كل عنصر في مجموعتي تم العمل عليه بنجاح (بدون خطأ) ، وبعد ذلك عندما ينبعث الخطأ الذي أنا مهتم به ، تعامل معه وفقًا لذلك. ثم ربما أنشئ مصفوفة جديدة من العناصر مع ضبط العلامة على false بالنسبة لأولئك الذين لم تتم معالجتهم بعد ، وقم بإجراء map أكثر من هذه العناصر ، مع التأكد من استدعاء رد الاتصال النهائي الأصلي من الخريطة الأصلية.

لست متأكدًا مما إذا كان هذا منطقيًا ، ولكن هل هناك أي طريقة لتحقيق ما وصفته أعلاه؟

question

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

مرحبًا @ parky128 ، شكرًا على السؤال!

هل يلف عمل iteratee بـ reflect ؟ reflect دوما بتمرير كائن نتيجة ل callback ، وذلك حتى إذا كان أحد iteratee أخطاء وظائف، و map سينتهي. بعد ذلك يمكنك فقط تكرار العنصر results من map ، وتحقق من العناصر التي تحتوي على خاصية error ، ثم التعامل معها وفقًا لذلك. لن تضطر إلى إعادة معالجة أي عناصر ربما لم تلتقطها map .

async.map(coll, async.reflect(function(val, callback) {
  // your request code
}, function(err, results) {
  // err will always be null now
  results.forEach(function(result, i) {
    if (result.error) {
      // your code for handling errors
      // if `coll` is an array, you could access the value that caused 
      // this error through `coll[i]` as `map` preserves the order for arrays 
    } else {
      // otherwise `result.value` will contain the result of that `iteratee` call
    }
  });
});

بخلاف ذلك ، للإجابة على سؤالك ، يُرجع map دائمًا array . يمكنك تكرار هذا المصفوفة والتحقق من القيم undefined . ستتوافق هذه مع العنصر (العناصر) التي إما أنها أخطأت أو مررت undefined إلى callback ، كانت قيد التقدم عندما حدث error أو لم يبدأ. ربما يكون الأسلوب reflect هو الخيار الأكثر أمانًا على الرغم من أن undefined قد يكون نتيجة صحيحة من مكالمة iteratee .

ال 5 كومينتر

مرحبًا @ parky128 ، شكرًا على السؤال!

هل يلف عمل iteratee بـ reflect ؟ reflect دوما بتمرير كائن نتيجة ل callback ، وذلك حتى إذا كان أحد iteratee أخطاء وظائف، و map سينتهي. بعد ذلك يمكنك فقط تكرار العنصر results من map ، وتحقق من العناصر التي تحتوي على خاصية error ، ثم التعامل معها وفقًا لذلك. لن تضطر إلى إعادة معالجة أي عناصر ربما لم تلتقطها map .

async.map(coll, async.reflect(function(val, callback) {
  // your request code
}, function(err, results) {
  // err will always be null now
  results.forEach(function(result, i) {
    if (result.error) {
      // your code for handling errors
      // if `coll` is an array, you could access the value that caused 
      // this error through `coll[i]` as `map` preserves the order for arrays 
    } else {
      // otherwise `result.value` will contain the result of that `iteratee` call
    }
  });
});

بخلاف ذلك ، للإجابة على سؤالك ، يُرجع map دائمًا array . يمكنك تكرار هذا المصفوفة والتحقق من القيم undefined . ستتوافق هذه مع العنصر (العناصر) التي إما أنها أخطأت أو مررت undefined إلى callback ، كانت قيد التقدم عندما حدث error أو لم يبدأ. ربما يكون الأسلوب reflect هو الخيار الأكثر أمانًا على الرغم من أن undefined قد يكون نتيجة صحيحة من مكالمة iteratee .

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

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

أنا فقط لا أريد خريطة غير متزامنة لمحاولة معالجة أي طلبات أخرى بمجرد أن يؤدي أحد هذه الطلبات إلى إرجاع حالة الخطأ التي أهتم بها.

أنا فقط لا أريد خريطة غير متزامنة لمحاولة معالجة أي طلبات أخرى بمجرد أن يؤدي أحد هذه الطلبات إلى إرجاع حالة الخطأ التي أهتم بها.

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

يمكنك تجربة mapSeries . mapSeries سيقوم بتشغيل طلب واحد فقط في كل مرة. أي أنه يستدعي العنصر التالي فقط عندما ينتهي العنصر الحالي من المعالجة (بدلاً من بدء كل منهم مرة واحدة). هذا يعني أنه عند حدوث خطأ ، واستدعاء رد الاتصال النهائي ، لن يتم تشغيل المزيد من iteratee s. يمكنك بعد ذلك مقارنة النتائج بالمجموعة لمعرفة العناصر التي لم تتم معالجتها بعد. لا يزال هذا حلًا بسيطًا ، لكنه أجمل من استخدام async.map . لكن العيب الرئيسي لهذا النهج هو أنه لم يعد يتم التعامل مع الطلبات بالتوازي.

على سبيل المثال ، إذا كانت مجموعتك عبارة عن مصفوفة

async.mapSeries(coll, function(val, callback) {
  // your iteratee function
}, function(err, results) {
  if (err) {
    // unprocessItems will include the item that errored.
    var unprocessItems = coll.slice(results.length - 1);
    // handle the unprocessedItems
  }
});

حسنًا ، نعم ، وظيفة التكرار الخاصة بي غير متزامنة لأنها تستخدم مكتبة الطلبات لإجراء طلب http صادر وأقوم بإعادة الاتصال منه بالنتيجة. لذلك إذا قلت أن هناك 10 عناصر للتكرار ، نجح 4 وفشل العنصر الخامس الذي سأستدعى بعد ذلك رد النداء لوظيفة iteratee مع معلمة خطأ ، إذا كان هذا يعني أن كائن النتائج في رد الاتصال النهائي إلى خريطة غير متزامنة سيحتوي فقط 4 نتائج ناجحة؟

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

hargasinski - لقد انتهيت من استخدام نهج async.reflect وهذا يعمل بشكل جيد بالنسبة لي ، ويعطيني رؤية كاملة لجميع العناصر التي أعطت خطأ: +1:

شكرا!

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