Bluebird NPM: وعد Bluebird JS مع مثال

⚡ ملخص ذكي

Bluebird JS هي مكتبة Promise كاملة الميزات لـ Javaنص برمجي تتمثل قدرته الأساسية في تحويل البيانات إلى وعود: تحويل وحدات Node القائمة على ردود الاتصال إلى وحدات تُرجع وعودًا، وبالتالي مكتبة كاملة مثل MongoDB يمكن استخدام برنامج التشغيل بشكل غير متزامن.

  • ؟؟؟؟ القدرة الأساسية: تقوم الدالة promisifyAll بتغليف كل طريقة من طرق الوحدة النمطية، وإضافة لاحقة Async التي تشير إلى أن الطريقة الآن تُرجع وعدًا.
  • 📦 تركيب: يقوم أمر npm install bluebird واحد بإضافة المكتبة، وبعد ذلك يقوم require بعرض كائن Promise.
  • 🔗 التسلسل: ثم يتلقى كل منها قيمة الدقة السابقة، والتي تحل محل عمليات الاستدعاء المتداخلة بتسلسل مسطح من الخطوات.
  • 🏷️ قاعدة التسمية: لا تُرجع سوى المتغيرات التي تنتهي بـ Async وعودًا؛ وتبقى طرق الاستدعاء الأصلية دون تغيير إلى جانبها.
  • 🛡️ مسار الفشل: يستقبل عنصر "الالتقاط" الوحيد في نهاية السلسلة رفضًا من كل خطوة سابقة.
  • 🇧🇷 السياق الحديث: تغطي الوعود الأصلية والانتظار غير المتزامن الآن معظم ما كان يوفره Bluebird بشكل فريد في السابق.

وعود بلو بيرد جيه إس

ما هو بلوبيرد JS؟

Bluebird JS هي مكتبة Promise كاملة الميزات لـ Javaيتميز هذا البرنامج النصي بقدرته الفائقة على تمكينك من "تحويل" وحدات Node الأخرى إلى "وعود" لاستخدامها بشكل غير متزامن. "الوعود" مفهوم يُطبق على دوال الاستدعاء، ويضمن أن كل دالة استدعاء تُرجع قيمة.

حتى إذا كان أ Node.js تحتوي الوحدة على دالة رد نداء لا تُرجع قيمة، مما يجعل الوحدة تقوم تلقائيًا بتعديل جميع الدوال الموجودة فيها بحيث تُرجع كل دالة قيمة.

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

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

كيفية إنشاء الوعود باستخدام مكتبة Bluebird JS

إليك مثال خطوة بخطوة يوضح كيفية إنشاء الوعود باستخدام مكتبة Bluebird JS.

الخطوة 1) تثبيت وحدات NPM

لاستخدام Bluebird من داخل تطبيق Node، يلزم تثبيت وحدة Bluebird. قم بتثبيتها باستخدام الأمر التالي:

npm install bluebird

الخطوة الثانية) تضمين وحدة بلو بيرد

الخطوة التالية هي تضمين وحدة Bluebird في التعليمات البرمجية الخاصة بك وتحويلها إلى وعد (Promises) بالكامل MongoDB الوحدة. يعني استخدام الوعود هنا أن Bluebird يضمن أن كل طريقة مُعرَّفة في MongoDB المكتبة ترجع الوعد.

قم بتضمين وحدات بلو بيرد

Code التفسير:

  1. استخدم require يتضمن الأمر مكتبة Bluebird.
  2. طائر أزرق .promisifyAll() تقوم هذه الطريقة بإنشاء نسخة غير متزامنة من كل طريقة MongoDB توفر الوحدة النمطية ذلك، لذا يعمل كل منها في الخلفية ويعيد وعدًا.

الخطوة 3) الاتصال بقاعدة البيانات

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

الاتصال بقاعدة البيانات

Code التفسير:

  1. تلاحظ connectAsync يتم استخدام هذه الطريقة بدلاً من الطريقة العادية connect الطريقة. يقوم بلو بيرد بإلحاق المتزامن لاحقة لكل طريقة في MongoDB مكتبة لتمييز الاستدعاءات التي تُرجع وعودًا عن تلك التي لا تُرجعها. لا تحمل الطرق التي لا تحمل اللاحقة Async أي ضمان من هذا القبيل.
  2. على غرار connectAsyncأطلقت حملة findAsync تقوم هذه الطريقة بإرجاع جميع السجلات في MongoDB مجموعة "الموظفين".
  3. If findAsync بعد نجاح العملية، تقوم الكتلة التالية بالتكرار عبر كل سجل في المجموعة وعرضه في سجل وحدة التحكم.

إذا تم تنفيذ الخطوات المذكورة أعلاه بشكل صحيح، فسيتم عرض جميع المستندات الموجودة في مجموعة الموظفين في وحدة التحكم، كما هو موضح في المخرجات أدناه.

يعد بلو بيرد بإخراج النتائج

إليكم الكود الكامل للاطلاع عليه:

var Promise = require('bluebird');

// promisifyAll adds an Async variant of every MongoDB method
var mongoClient = Promise.promisifyAll(require('mongodb')).MongoClient;

mongoClient.connectAsync('mongodb://localhost/EmployeeDB')

    .then(function(db) {
        return db.collection('Employee').findAsync({});
    })
    .then(function(cursor) {
        cursor.each(function(err, doc) {
            console.log(doc);
        });
    });

⚠️ ملاحظة حول إصدار برنامج التشغيل: يستهدف الكود أعلاه MongoDB برنامج تشغيل Node 2.x، حيث connect يتم حلها باستخدام كائن قاعدة البيانات. من برنامج التشغيل 3.0 فصاعدا وينتهي الأمر بـ MongoClientلذلك يجب على السلسلة أن تتصل client.db('EmployeeDB').collection('Employee') بدلا من db.collection('Employee')كما أن إصدارات برامج التشغيل الحديثة تُعيد وعودًا أصلية بالفعل، مما يجعل promisifyAll غير ضروري لـ MongoDB على وجه التحديد.

بلو بيرد مقابل الوعود الأصلية: أيهما تستخدم؟

عندما كُتبت مكتبة Bluebird لأول مرة، لم يكن لدى Node أي دعم للوعود على الإطلاق، لذا سدّت هذه المكتبة ثغرة حقيقية في المنصة. وقد أضاف Node دعمًا أصليًا للوعود منذ الإصدار 4. async/await منذ الإصدار 7.6، والذي يغير الحساب بشكل كبير لأي شخص يبدأ مشروعًا اليوم.

البعد بلوبيرد وعود السكان الأصليين
التبعية حزمة npm للتثبيت والصيانة مدمج في وقت التشغيل
ردود الاتصال الواعدة promisifyAll() يحول وحدة كاملة util.promisify() يحوّل دالة واحدة
مساعدون إضافيون الخريطة، التصفية، الخصائص، كل، المهلة، الإلغاء جميع، جميع المستقرين، أي، عرق فقط
كومة طويلة traces نعم، عند التفعيل محسّن لكن أقصر
أفضل ل مكتبات الاستدعاء القديمة، ومساعدات التزامن الكود الجديد، وأي شيء يستخدم async await

اختر الوعود الأصلية للمهام الجديدة، لأنها لا تحتاج إلى أي تبعيات وتتكامل مباشرةً مع async/await. استخدم Bluebird عندما لا تزال التبعية تعرض ردود الاتصال فقط، أو عندما تكون أدوات المساعدة الخاصة بالتزامن، مثل Promise.map مع وجود حد للتزامن، يمكنك توفير قدر كبير من التعليمات البرمجية.

كيفية التعامل مع الأخطاء باستخدام وعود بلو بيرد

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

يدعم بلو بيرد .catch() للرفض و .finally() للتنظيف الذي يجب تنفيذه في كلتا الحالتين. كما يدعم أيضًا عمليات الالتقاط المُحددة النوع، والتي تعالج نوعًا واحدًا من الأخطاء مع السماح للأنواع الأخرى بالانتشار.

var Promise = require('bluebird');
var mongoClient = Promise.promisifyAll(require('mongodb')).MongoClient;

var connection;

mongoClient.connectAsync('mongodb://localhost/EmployeeDB')
    .then(function(db) {
        connection = db;
        return db.collection('Employee').findAsync({});
    })
    .then(function(cursor) {
        return cursor.toArrayAsync();
    })
    .then(function(docs) {
        docs.forEach(function(doc) { console.log(doc); });
    })
    .catch(Promise.TimeoutError, function(err) {
        console.error('The database did not respond in time.');
    })
    .catch(function(err) {
        // Any other rejection from any step above arrives here
        console.error('Query failed:', err.message);
    })
    .finally(function() {
        // Runs on success and on failure, so the socket always closes
        if (connection) { connection.close(); }
    });

ثلاث عادات مهمة هنا. أولاً، ضع .catch() في النهاية بدلاً من بعد كل خطوة، لأن معالج طرفي واحد يتلقى رفضًا من كل حلقة سابقة في السلسلة. ثانيًا، استخدم .finally() لتحرير موارد مثل اتصال قاعدة البيانات، حيث يعمل في كلتا حالتي النجاح والفشل. ثالثًا، لا تترك سلسلة بدون معالجة: يؤدي الرفض غير المعالج إلى إنهاء عملية Node في الإصدارات الحالية، وسيقوم Bluebird بطباعة تحذير صريح بشأنه مسبقًا. تفعيل المكدس الطويل tracأثناء التطوير مع Promise.config({ longStackTraces: true }) يجعل ذلك تحديد مصدر الرفض أسهل بكثير.

أخطاء شائعة في برنامج Bluebird Promisify وحلولها

تنشأ معظم مشاكل مكتبة Bluebird من اصطلاح التسمية القائم على الوعود، أو من خلط أساليب استدعاء الدوال المستدعاة والوعود في نفس السلسلة، وليس من أي خلل في المكتبة نفسها. كل عرض من الأعراض المذكورة أدناه يحدد سببه وحلّه.

  • "connectAsync ليست دالة": كان مطلوبًا بشكل مباشر بدلاً من خلال promisifyAll()لذا لا توجد متغيرات غير متزامنة. قم بتغليف استدعاء require كما هو موضح أعلاه.
  • استدعاء الدالة العادية والحصول على قيمة غير مُعرَّفة: connect() لا يزال ينتظر رد اتصال. النسخة التي تحمل لاحقة Async فقط هي التي تُرجع وعدًا.
  • تمرير دالة رد نداء إلى دالة غير متزامنة: لا يتم توفير رد اتصال ولا await ويتم تنفيذ الوعد دون ملاحظة. استخدم نمطًا واحدًا لكل استدعاء، وليس كليهما.
  • promisifyAll على مكتبة تعتمد بالفعل على الوعود: غير ضار ولكنه عديم الفائدة، وينتج عنه أسماء ذات لاحقة مزدوجة مربكة. راجع وثائق المكتبة أولاً.
  • فقدان الأخطاء بصمت: سلسلة بدون .catch() يخفي سبب الرفض حتى يُبلغ Node عن رفض غير معالج ويخرج. أنهِ السلسلة دائمًا باستخدام catch، حتى في البرامج النصية القصيرة.

الأسئلة الشائعة

تُضيف الدالة `promisifyAll` نسخةً من كل دالة بدلاً من استبدالها، مما يُحافظ على استمرار عمل النسخة الأصلية من الدالة المُستدعاة. ويُشير اللاحق `Async` إلى النسخة التي تُعيد وعدًا. ويمكن ضبط هذا اللاحق من خلال خيار `promisifier`.

نعم. وعود بلو بيرد متوافقة مع معايير Promises/A+، لذا await يقبلها تمامًا مثل الوحدات الأصلية. يتيح لك هذا تحويل وحدة قديمة إلى وعد ثم استخدامها باستخدام الصيغة الحديثة.

نعم. AI يقوم المساعدون بإعادة كتابة الاستدعاءات المتداخلة في سلاسل وعود أو باستخدام async await بشكل موثوق. تحقق من معالجة الأخطاء لاحقًا، لأن التحويلات المُولَّدة غالبًا ما تُهمل عبارة catch النهائية.

أدوات منظمة العفو الدولية tracإذا كان أحد روابط السلسلة يفتقر إلى عبارة إرجاع، فإن السبب المعتاد لرفض الطلب هوpingكما أنها تشير إلى السلاسل التي تفتقر إلى معالجة نهائية، وهو ما يحول الخطأ المعالج إلى عطل.

تنتظر الدالة Promise.all مصفوفة موجودة من الوعود. أما الدالة Promise.map في Bluebird فتبنيها من القيم وتقبل حدًا للتزامن، مما يمنع آلاف الطلبات المتزامنة من استنفاد المقابس.

تلخيص هذه التدوينة بـ: