Async: دعم وظيفة "غير متزامن"

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

أحد الأفيال في الغرفة هو الدعم الجديد async / await الذي وصل إلى Node و Chrome ، وسرعان ما سيصل إلى كل متصفح رئيسي آخر. كنت أفكر فيما يمكن أن يفعله Async في العالم async / await .

حاليًا ، يمكننا تكييف وظائف async عن طريق تغليفها بـ asyncify . نظرًا لأن الوظيفة async هي في الأساس مجرد وظيفة تقوم بإرجاع وعد ، يمكن لهذا المحول القديم تحويلها بسهولة إلى وظيفة نمط رد الاتصال. ومع ذلك ، فإنه يؤدي إلى المظهر السخيف إلى حد ما:

async.mapLimit(arr, 10, async.asyncify(async (val) => {
  let foo = await doSomething(val);
  //...
 return bar;
}), done);

ومع ذلك ، فإن إحدى الميزات في مواصفات وظائف async هي:

Object.getPrototypeOf(asyncFn)[Symbol.toStringTag] === "AsyncFunction"

يوفر هذا طريقة لاكتشاف الوظائف (الأصلية) async بسهولة. يمكننا استخدام هذه التقنية للحصول تلقائيًا على asyncify لهم. يصبح المثال أعلاه:

async.mapLimit(arr, 10, async (val) => {
  let foo = await doSomething(val);
  //...
 return bar;
}, done);

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

let result = await pify(async.mapLimit)(arr, 10, async (val) => {
  let foo = await doSomething(val);
  //...
 return bar;
});

الطريقة المذكورة أعلاه لاكتشاف وظائف async تعمل فقط مع الدوال الأصلية. لا أعتقد أن هناك طريقة لاكتشاف وظائف Babel transpiled. بالتأكيد لا يمكننا الكشف عن الوظائف العادية التي ترجع ببساطة الوعود ، لأنه سيتعين علينا بأثر رجعي عدم تمرير رد الاتصال. سيكون هناك تحذير كبير بأن هذا لن يعمل إلا بدون محول في البيئات الحديثة جدًا ، وإلا فلا يزال يتعين عليك الالتفاف يدويًا بـ asyncify .

أيضًا ، من المسلم به أن العديد من طرق Async لا معنى لها مع async / await . يتم نسخ معظم طرق التحكم في التدفق (باستثناء أشياء مثل auto و queue ) بسهولة أكبر باستخدام تركيبات تدفق التحكم الأصلية. يمكن استبدال map و parallel بـ Promise.map و Promise.all . ومع ذلك ، فإن وظائف التجميع المحددة ستكون مفيدة للغاية ، بالإضافة إلى auto وعدد قليل من الوظائف الأخرى. (أيضًا ، autoInject مع وظائف async هو حلم للتحكم في التدفق غير المتزامن!)

enhancement feedback-wanted

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

هل هناك سبب للقيام Object.getPrototypeOf(asyncFn)[Symbol.toStringTag] === "AsyncFunction" أو هل يمكننا عمل asyncFn[Symbol.toStringTag] === "AsyncFunction" (يبدو أننا نعمل في FF)؟

هذه مجرد طريقة مواصفات ECMA الأساسية للقيام بذلك. أعتقد من الناحية النظرية ، يمكن لأي شخص الكتابة فوق asyncFn[Symbol.toStringTag] .

إذن هل الاقتراح في أي وقت يقدم فيه شخص ما إعادة اتصال بالتنسيق cb (err، arg) يجب أن نكتشف ما إذا كانت دالة Async؛ إذا كانت وظيفة غير متزامنة ، فيجب علينا التعهد باستخدامها كما هي

اعتقد ان لديك قليلا الى الوراء. أينما نقبل دالة تكرار قبول رد الاتصال ( function(args..., callback) {} ) ، يجب علينا التحقق لمعرفة ما إذا كانت دالة async ، ثم asyncify it.

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

ال 10 كومينتر

سأفكر في هذا أكثر ولكن أود أن أطرح سؤالين تقنيين فقط حتى أتمكن من محاولة تصور شكل هذا بشكل أفضل ..

هل هناك سبب للقيام Object.getPrototypeOf(asyncFn)[Symbol.toStringTag] === "AsyncFunction" أو هل يمكننا عمل asyncFn[Symbol.toStringTag] === "AsyncFunction" (يبدو أننا نعمل في FF)؟

إذاً هو الاقتراح في أي وقت يقدم فيه شخص ما إعادة اتصال بالتنسيق cb(err, arg) يجب أن نكتشف ما إذا كان هو AsyncFunction ؛ إذا كانت وظيفة غير متزامنة ، فيجب علينا تطبيق promisify وإلا استخدمها كما هي

آسف أيضًا ، أنا لا أتابع مثال الانتظار ، إذا اكتشفنا أن الوظيفة هي AsyncFunction ما هي تحديات دعم await ؟

هل هناك سبب للقيام Object.getPrototypeOf(asyncFn)[Symbol.toStringTag] === "AsyncFunction" أو هل يمكننا عمل asyncFn[Symbol.toStringTag] === "AsyncFunction" (يبدو أننا نعمل في FF)؟

هذه مجرد طريقة مواصفات ECMA الأساسية للقيام بذلك. أعتقد من الناحية النظرية ، يمكن لأي شخص الكتابة فوق asyncFn[Symbol.toStringTag] .

إذن هل الاقتراح في أي وقت يقدم فيه شخص ما إعادة اتصال بالتنسيق cb (err، arg) يجب أن نكتشف ما إذا كانت دالة Async؛ إذا كانت وظيفة غير متزامنة ، فيجب علينا التعهد باستخدامها كما هي

اعتقد ان لديك قليلا الى الوراء. أينما نقبل دالة تكرار قبول رد الاتصال ( function(args..., callback) {} ) ، يجب علينا التحقق لمعرفة ما إذا كانت دالة async ، ثم asyncify it.

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

نفذ في # 1390!

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

ملاحظة: شكرًا لكل العمل الرائع الذي تقوم به بهذه المكتبة

أطلق النار! ما كسر. هل يمكنك من فضلك إنشاء تذكرة مع تفاصيل
البيئة التي لم يعمل فيها هذا؟
شكرا!

يوم الأربعاء 5 أبريل 2017 الساعة 10:18 صباحًا مانويل فالس فرنانديز <
[email protected]> كتب:

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

ملاحظة: شكرًا لكل العمل الرائع الذي تقوم به بهذه المكتبة

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

متفق عليه ، لقد كسر بنائي أيضًا ...

الشلال الذي كان يستدعي وظيفة غير متزامنة والتي عملت قبل أيام قليلة بدأت بالفشل مع "cb is not function" لأن رد الاتصال غير المتزامن لم يعد متوفرًا للوظيفة.

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

aearly من فضلك ، لا تذكر ذلك !! إنه لطف منك حقًا أن تجيب: 1st_place_medal:

ألمح manvalls لي إلى حل رائع لا يتطلب التراجع. نظرًا لأنك تستخدم الرمز لاكتشاف async في إعلان الوظيفة ، فقد فكر في طريقة ذكية لخداع الاكتشاف.

كان شلالتي يستخدم وظائف تم تصديرها من وحدات نمطية أخرى ، كان أحدها async واحد وبالتالي تسبب في الفشل.

لذلك فقط عن طريق التغيير من:

... 
/* services module */
function doThis(param, cb) {
...
}

async function doThatAsync(param, cb) {
...
}

module.exports = {
  doThis: doThis,
  doThat: doThatAsync  
}; 

...
async.waterfall([
  services.doThis,
  services.doThat,  // fails with "cb is not a function"
], err => {
...
}

ل:

... 
/* services module */
function doThis(param, cb) {
...
}

async function doThatAsync(param, cb) {
...
}

module.exports = {
  doThis: doThis,
  doThat: (...args) => doThatAsync(..args)   // cheating the detection
}; 

...
async.waterfall([
  services.doThis,
  services.doThat, /* it works!!! */
], err => {
...
}

شكرا جزيلا مجددا

هل يمكننا استخدام async / wait مع async.autoInject ()؟

async.autoInject({

    conn1: async function () {
      return conn1;
    },

    conn2: async function () {
      return conn2;
    },
});

لا يبدو أنه يعمل ، أحصل على:

خطأ: تتطلب وظائف مهمة الإدخال التلقائي معلمات صريحة.
في /Users/alexamil/WebstormProjects/nabisco/cdt-now/node_modules/async/dist/async.js:2081:23
في / Users / alexamil / WebstormProjects / nabisco / cdt-now / node_modules / غير متزامن

ORESoftware نعم ، يجب أن تعمل وظائف async مع autoInject . لقد اختبرت الكود الذي نشرته في Chrome ، وتم تشغيله. حصلت على ReferenceError في رد الاتصال النهائي حيث conn1 و conn2 هي undefined . بعد تغييره إلى

async.autoInject({
    conn1: async function () {
      return 'foo'
    },
    conn2: async function () {
      return 'bar'
    },
})

أنه يعمل بشكل جيد. ومع ذلك ، فإننا لا ندعم الوظائف المترجمة async . هل تقوم بنقل الكود الخاص بك؟

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