Async: إعداد معالجات الأحداث باستخدام Async

تم إنشاؤها على ٢٥ أكتوبر ٢٠١٦  ·  4تعليقات  ·  مصدر: caolan/async

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

فيما يلي مثال مبسط يوضح المشكلة:

async.auto({
  // This needs to run first, but it will finish second
  event: [(next) => {
    emitter.once('awesome', next);
  }],

  // This needs to finish near the end
  checkResults: ['event', (results, next) => {
    assert(results.event.status == 200);
    assert(results.event.msg == 'cool');

    // Do other async stuff...
    somethingAsync(next);
  }],

  // This has to start second, but before the first one finishes
  emit: ['event', (results, next) => {
    event.emit('awesome', {msg: 'cool'}, next);
  }],

  checkEmit: ['emit', (results, next) => {
    // some sort of check that can be async
  },
], done);

يجب أن يبدأ event أولاً ، لكنه لن ينتهي حتى يظهر emit . يحتاج emit إلى الانتظار حتى يبدأ event ، ولكن لا ينتهي (يُعرف أيضًا باسم إعداد المعالج). وبالتالي هذا لن ينتهي.

هل هناك طريقة للقيام بذلك مع مكتبة غير متزامنة الحالية؟ (بطريقة نظيفة)

هذا هو الحل الذي أرغب فيه ، بافتراض أنه يمكن تنفيذه بطريقة غير متزامنة

async.auto({
  listen: [(next, done) => {
    client.on(done);
    return next();
  },

  ...
}, callback);

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

question

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

أعتقد أن هذه هي أكثر حالات استخدام السيارات جنونًا التي رأيتها بالمناسبة: building_construction:

ال 4 كومينتر

مرحبا Saevon ، شكرا على السؤال!

هناك طريقة سريعة ونظيفة للقيام بذلك وهي:

async.auto({
    // This needs to finish near the end
  checkResults: [(next) => {
    return next(null, (results, next) => {
      assert(results.event.status == 200);
      assert(results.event.msg == 'cool');

      // Do other async stuff...
      // somethingAsync(next);
    });
  }],

  // This needs to run first, but it will finish second
  event: ['checkResults', (handler, next) => {
    emitter.once('awesome', handler.checkResults);
    return next();
  }],

  // This has to start second, but before the first one finishes
  emit: ['event', (results, next) => {
    // Should this be emitter.emit instead of event.emit?
    event.emit('awesome', {msg: 'cool'}, next);
  }],

  checkEmit: ['emit', (results, next) => {
    // the results of `checkResults` will be in `results.emit`
    // as the handler on 'awesome' was passed the `next`
    // callback from `emit`

    // some sort of check that can be async
    yourChecks(next);
  }]
}, function done(err) {
    // everything finished running, unless `err` !== `null`
});

بشكل أساسي ، تقوم فقط بتبديل التبعية event و checkResults ، والتي قد تكون في الواقع أكثر نظافة ، حيث يعتمد event على المعالج في checkResults . checkResults بتمرير المعالج إلى event .

سيكون أمر التنفيذ:
checkResults --> event --> emit --> handler (passed to event from checkResults) --> checkEmit --> done .

اسمحوا لي أن أعرف إذا كان أي شيء غير واضح.

نعم ، هذا يحل المشكلة. شكرا!

أعتقد أن هذه هي أكثر حالات استخدام السيارات جنونًا التي رأيتها بالمناسبة: building_construction:

متفق. عادةً لا تختلط عمليات الاسترجاعات غير المتزامنة وبواعث الأحداث جيدًا ...

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