Async: وعد بالدعم

تم إنشاؤها على ١٣ نوفمبر ٢٠١٥  ·  22تعليقات  ·  مصدر: caolan/async

أضف دعم الوعد للسماح بمزج المهام المختلفة:

async.waterfall([
    function (done) {
        // Do something and call done()
        fs.readFile(filepath, done);
    },
    function(content) {
        // Do something and return Promise
        return mongoose.models.file.create({
            name: filepath,
            content: content
        });
    }
], (err) => {
    if (err) {
        console.error(err);
    }
});
feature

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

أعتقد أنه مثلما يوجد غير متزامن ، يمكن أن يكون هناك وظيفة غير متزامنة.

ثم يمكنني انتظار عدم التزامن. promisify (async.mapLimit (x، 10، mapper))

ال 22 كومينتر

سيأخذ asyncify وظيفة متزامنة تُرجع وعدًا وتستدعي رد اتصال على معالجاتها التي تم حلها / رفضها:

async.waterfall([
    function (done) {
        // Do something and call done()
        fs.readFile(filepath, done);
    },
    async.asyncify(function(content) {
        // Do something and return Promise
        return mongoose.models.file.create({
            name: filepath,
            content: content
        });
    })
], (err, model) => {
    if (err) {
        console.error(err);
    }
});

لكن هذه الميزة غير موثقة ...

كان لدي أيضًا فكرة أخرى - هل يجب علينا تلقائيًا إلغاء تزامن الوظائف التي تعيد الوعود (أو التعامل معها بشكل مناسب؟). ما الذي يجب أن يفعله غير المتزامن عند تمرير دالة ES-مهما كانت async (التي تُرجع ضمنيًا وعدًا)؟

على سبيل المثال

async.waterfall([
    function (done) {
        // Do something and call done()
        fs.readFile(filepath, done);
    },
    async function(content) {
        return await mongoose.models.file.create({
            name: filepath,
            content: content
        });
    }
], (err, model) => {
    if (err) {
        console.error(err);
    }
});

أنا شخصياً أعتقد أن عدم التزامن يجب أن يتجاهل الوعود بشكل افتراضي. هناك بعض الوظائف غير المتزامنة التي أكتبها والتي يجب عليّ أيضًا إدخالها في async.queue ، لكنني لا أريد كتابة هذا:

import {queue, asyncify} from 'async'

const run = asyncify(async function () {
  await someStuff()
})

const q = async.queue(run)
q.push('asdf')

حيث يمكنني كتابة هذا

import {queue} from 'async'

async function run () {
  await someStuff()
}

const q = async.queue(run)
q.push('asdf')

تمت إضافة المستندات مقابل asyncify . الذهاب إلى إبقاء هذا مفتوحًا لسلوك عدم التزامن التلقائي.

حول هذا الأمر ، كنت أقوم بتجربة استخدام نفس مصدر البرنامج واستخدام واجهة Promise للطرق التي تستخدم رد الاتصال كمعامل أخير. تحقق منه !

async.waterfall([
  function (callback) {
    callback(null, 'one', 'two')
  },
  function (arg1, arg2, callback) {
    // arg1 now equals 'one' and arg2 now equals 'two'
    callback(null, 'three')
  },
  function (arg1, callback) {
    // arg1 now equals 'three'
    callback(null, 'done')
  }
]).then(function (value) {
  console.log(value === 'done')
})

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

مثير جدا. إذا تعامل Async بشكل صحيح مع الوظائف التي تعيد الوعود ، فيمكنه أيضًا قبول وظائف Async الموعودة بسهولة تامة. هذا من شأنه أن يعمل:

async.parallel([
  async.waterfall([
    asyncFn1,
    function (result1, next) {
      //...
    }
    asyncFn2,
    //...
  ]), // no callback!
  async.each(arr, function (item, cb) {
    //...
  })
  otherAsyncFn
], done)

سيكون من الأسهل بكثير الجمع بين وظائف Async.

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

ومع ذلك ، إذا كان إلغاء رد النداء النهائي من طريقة ما قد أعاد وعدًا ، وإذا تم إعداد Async للتعامل مع الوظائف التي تُرجع الوعود ، فسيكون ذلك مزيجًا مثيرًا للاهتمام. إحدى المشكلات الرئيسية هي أن Async يجب أن يتكامل مع مكتبة الوعد - أيهما؟ هل نعتمد على global.Promise ، مما يؤدي إلى إجبار المحركات القديمة على إعادة التعبئة ، أم أننا نستخدم شيئًا مثل Bluebird؟ أيضًا ، Async هو نوع من بيان ضد الوعود - وظائف ذات ترتيب أعلى لوظائف قبول رد الاتصال ، بدلاً من اعتماد نموذج Futures. أنا جميعًا مع إمكانية التشغيل البيني مع Promises ، لكنني أعتقد أن الحصول على وعود Async بالعودة هو قليلاً خارج فلسفة التصميم الخاصة به.

aearly

أشعر أن Promises عبارة عن سير عمل يتماشى مع إصدارات العقدة الأخيرة (> = 4). تتوفر الوعود في هذه الإصدارات ، لذا فإن رؤيتي هي استخدام مسار عمل الوعد عندما يكون لدى البيئة العالمية وعود.

من الممكن إضافة polyfill صغير (تحقق من وعد الخنصر ) ولكن في رأيي ليس له معنى يوفر polyfill. من الأفضل إجبار المستخدم على ترقية إصدار العقدة لاستخدام ميزات العقدة الأخيرة. حقًا ، تحقق (حصلت على 6 علاقات عامة) [https://github.com/sindresorhus/got/pull/140]. التبعيات غير مرحب بها في مشروع صغير جدًا ويتم استخدامها في كل مكان.

ربما يكون من الجيد تضمين هذه الميزة بعد تشكيل نمطية غير متزامن ، بحيث يكون من السهل تكييف قاعدة الكود.

لكن بالتأكيد ، التوافق غير المتزامن مع الوعود هو _ يجب_ تمامًا!

Kikobeats : +1:

أصبحت الوعود من الدرجة الأولى وظائف غير متزامنة. لذلك من الصعب تخيل المكتبة الضرورية لعدم التزامن بدون دعم كامل لها.

أعتقد أنه يمكن تنفيذه بدون polyfill ولكن مع اكتشاف الميزة: السماح إذا كان هناك كائن Promise عالمي باستخدام طريقة resolve .

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

martinheidegger Bluebird كبير جدًا لهذا. سوف يلقي 76 كيلو بايت (مصغر) لدعم بسيط لطرق الوعد.

مرة أخرى ، يعد استخدام رد الاتصال أو واجهة الوعود في سير عمل الواجهة الخلفية عملية طبيعية تستند إلى إصدار العقدة.

  • إذا كان لديك المزيد من الوقت الخلفي (ربما سنتان أو أكثر) ، فأنت تستخدم الإصدار 0.10 أو 0.12 ، لذلك ، تتم كتابة الكود الخاص بك بأسلوب رد الاتصال.
  • إذا كانت الواجهة الخلفية لديك أقل من 6 أشهر تقريبًا وكنت تستخدم إصدار العقدة >=4 المحتمل أنك تستخدم نمط الوعد.

لكن على أي حال ليس لديك أسلوب مختلط.

لذلك ليس من الضروري إضافة التبعية لدعم الوعود ؛ إذا كان غير المتزامن يدعم الوعود يومًا ما في المستقبل ، فيمكنك استخدامه إذا كان إصدار العقدة لديك يدعم الوعود.

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

نفس السلوك لواجهة الواجهة. لا التبعية ضرورية.

حسنًا ، يبدو أن نفس المشكلات التي واجهتها شركة Promises قبل 4-5 سنوات لا تزال سارية. إذا كان الجميع يستخدم العقدة 4 أو أحدث ، والمتصفحات الحديثة التي تدعم ES6 ، فيمكننا بسهولة استخدام الوعود داخليًا حيثما أمكن ذلك.

المشكلة هي أننا نترك عقدة 0.12 ومستخدمي المتصفح الأكبر سنًا في الغبار ، مما يتطلب منهم إعادة التعبئة. أي polyfill يستخدمون؟ لا نريد تجميع واحدة ، حتى الوعد الخنصر له وزنه. أيضًا ، سيرغب الأشخاص الذين يستخدمون وعودًا خارج نطاق ES6 Promise القياسي في استخدام بلوبيرد أو q وما إلى ذلك ، مهما كان ما يستخدمونه. لا أريد أن أطلب استخدام polyfill - npm i -S async يجب أن يكون كل ما يحتاجه الناس.

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

أنا أؤيد جميعًا التداخل مع الوعود ، إذا تم تمرير وظيفة ما في وعد أو "غير ممكن" مما ينبغي علينا بالتأكيد الاستفادة منه. لكن أعتقد أنه يجب علينا تجنب إنشاء و / أو إرجاع الوعود داخليًا ، فقط لأن دعم ES6 عبر الأنظمة الأساسية لا يزال أمامه طريق لنقطعه.

متفق عليه ، الوعود ليست رخيصة في الإنشاء أو المعالجة. أفضل أن أرى شيئًا كهذا على أنه امتداد للتمكين. الوعود عظيمة لكنك لن تريدها دائمًا

IMHO ، بعد ترحيل الكثير من كود العقدة إلى وعود + عائد مشترك ، لم أجد بديلًا مباشرًا فقط لـ .eachLimit() . ربما تكون قائمة الحالات المفيدة أقل بكثير مما تبدو للوهلة الأولى ، ويمكن التعامل معها بحزمة منفصلة.

أحب الامتداد الصغير لـ Kikobeats ، فقد يكون من المنطقي أن أوصي به في الملف التمهيدي (/ ccaearly).

سأعارض بشدة الدعم الرسمي للوعود غير المتزامنة لأسباب طرحها أنا والمستخدمون الآخرون.

megawac ماذا عن الحالة التي ترجع فيها الوظيفة وعدًا؟ مثال SEAPUNK .

megawac لقد الوعد غير المتزامن . ثم إذا أراد أي شخص استخدام Promise ، أعتقد أنه جاهز: +1:

@ في وقت مبكر ، سيكون ذلك جيدًا على ما أعتقد (لذا =) لكنني أفضل تركه في البرنامج المساعد
تهبط شخصيًا

يوم الجمعة ، 22 يناير 2016 الساعة 2:17 مساءً ، Kiko Beats [email protected]
كتب:

megawac https://github.com/megawac أضفت دعمًا لنمط رد الاتصال
واختبارات الوعد غير المتزامن
https://github.com/Kikobeats/promise-async#promise -async. ثم إذا
أي شخص يريد استخدام Promise ، أعتقد أنه جاهز [الصورة:: +1:]

-
قم بالرد على هذا البريد الإلكتروني مباشرة أو قم بعرضه على GitHub
https://github.com/caolan/async/issues/956#issuecomment -174016628.

إليك حزمة أخرى تعد بجميع الطرق غير المتزامنة المتاحة:
https://github.com/eladnava/koa-async

أعتقد أنه مثلما يوجد غير متزامن ، يمكن أن يكون هناك وظيفة غير متزامنة.

ثم يمكنني انتظار عدم التزامن. promisify (async.mapLimit (x، 10، mapper))

لن أعترض على ذلك إذا كنت تريد إنشاء طلب سحب

يوم السبت 17 ديسمبر 2016 الساعة 4:57 مساءً ، Manoj Patel [email protected]
كتب:

أعتقد أنه مثلما يوجد غير متزامن ، يمكن أن يكون هناك عدم التزامن
وظيفة.

ثم يمكنني انتظار عدم التزامن. promisify (async.mapLimit (x، 10، mapper))

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/caolan/async/issues/956#issuecomment-267789633 ، أو كتم الصوت
الخيط
https://github.com/notifications/unsubscribe-auth/ADUIEKJIDulPHAn_SeEZbiPb3t7ORGnpks5rJFqvgaJpZM4Gh1fr
.

أنا أستخدم طريقة بوحدة bluebird لتحويل عمليات الاسترجاعات إلى وعود بحيث تصبح أساليب غير متزامنة :

// adds '<original-method>Async' to class 
Promise.promisifyAll(async);

function somePromise() {
    return async.parallelAsync([
        function(cb) {
            setTimeout(function(){
                cb(new Error('err'), 'foo')
            }, 1000);
        },
        function(cb) {
            setTimeout(function(){
                cb(null, 'bar')
            }, 1000);
        }
    ]);
}

somePromise().then(function(result){
    console.log('result',result);
}).catch(function(err){
    console.log('err',err);
});

مثال JSFiddle

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