أحد الأفيال في الغرفة هو الدعم الجديد 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
هو حلم للتحكم في التدفق غير المتزامن!)
سأفكر في هذا أكثر ولكن أود أن أطرح سؤالين تقنيين فقط حتى أتمكن من محاولة تصور شكل هذا بشكل أفضل ..
هل هناك سبب للقيام 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
. هل تقوم بنقل الكود الخاص بك؟
التعليق الأكثر فائدة
هذه مجرد طريقة مواصفات ECMA الأساسية للقيام بذلك. أعتقد من الناحية النظرية ، يمكن لأي شخص الكتابة فوق
asyncFn[Symbol.toStringTag]
.اعتقد ان لديك قليلا الى الوراء. أينما نقبل دالة تكرار قبول رد الاتصال (
function(args..., callback) {}
) ، يجب علينا التحقق لمعرفة ما إذا كانت دالةasync
، ثمasyncify
it.المثال
await
هو ما كان سيفعله شخص ما إذا أراد طريقة غير متزامنةawait
. لا أعتقد أنه يجب أن تبدأ طرق Async في إرجاع الوعود حتى تنجح - اترك الأمر للمستخدم ليفعله.