Tamim Fahed نشر 3 مارس 2021 أرسل تقرير نشر 3 مارس 2021 (معدل) استخدم node js من طرف السيرفر ولدي حلقة تقوم بإنشاء اتصال socket IO مع سيرفر آخر ويجب انتظار النتيجة ثم تنفيذ باقي التعليمات وتكرار الحلقة. ولكن ذلك لا يحصل. هذا هو الكود: exports.placeOrders = async (socket, orders) => { for await (order of orders){ console.log("Order ID: " + order.id); socket.emit('requestOrderDetails', order.id); await socket.on('getDetails' , async (response) => { console.log("order details:" + response); await .. await .. }) } console.log("Process Finished); } الحلقة تقوم بالمرور على الطلبات orders وعند كل طلب تقوم بجلب باقي التفاصيل من السيرفر الآخر عن طريق socket. ولكن بدلاً من الحصول على النتائج بالترتيب أحصل على التالي: Order ID: Process Finished Order details: ولكن الترتيب الصحيح هو 1-order ID 2-order details 3-process finished حاولت استخدام for await وأيضاً حلقة for العادية ولكن نفس النتيجة. ما الحل؟ تم التعديل في 3 مارس 2021 بواسطة Tamim Fahed اقتباس
0 Wael Aljamal نشر 3 مارس 2021 أرسل تقرير نشر 3 مارس 2021 عليك تقسم الكود إلى تابعين الأول يمر على orders والثاني ينفذ التعليمات الخاصة بكل order. التابع الذي يقوم بتنفيذ التعليمات ضمن حلقة for يجب استدعائه عن طريق await. عند الحاجة لانتظار أكثر من حدث للانتهاء عليك استخدام promise all. 1 اقتباس
0 محمد أيت لعرايك نشر 3 مارس 2021 أرسل تقرير نشر 3 مارس 2021 تعمل الدالات غير المتزامنة async على إرجاع قيمة Promise ، وهو مكون من شأنه أن رجعة قيمة معينة أو أن يرجع قيمة خطا (error) . يعني أن await تطلب من البرنامج التوقف وإنتظار قيمة promise. في بعض الأحيان نضطر أن نستعمل await داخل حلقة loop مثلا: const fruits = ['apple', 'grape', 'pear'] console.log('بداية') for (let index = 0; index < fruits.length; index++) { const fruit = fruits[index] // لنفترض أن هذه دالة تقوم بجلب إسم فاكهة معينة من الخادم const fruitInfo = await getfruitInfo(fruit) console.log('fruitInfo') } console.log('نهاية') } //--------------- نتيجة هذا الكود سوف تكون كالتالي --------------- /* 'بداية' 'Apple' 'Grape' 'Pear' 'نهاية' */ في هذه الحالة await تعمل بالشكل المطلوب كما تريد أن تكون في الكود الخاص بك لكن في حالة كانت getfruitInfo تحتاج إلى callback كمعطى parameter فلن تعمل الحلقة كما يبغي لأن في الحلقة loop يوجد مجموعة من promises لم تنتهي بعد ولذلك تظهر process finished قبل نهاية الحلقة والحل هو إستخدام await Promise.all(arrayOfPromises). وبالتالي الكود الخاص بك يجب أن يكون على الشكل التالي: exports.placeOrders = async (socket, orders) => { for await (order of orders){ console.log("Order ID: " + order.id); socket.emit('requestOrderDetails', order.id); const promises = await socket.on('getDetails' , async (response) => { console.log("order details:" + response); }) } // pormises هنا يجب أن نجبر البرنامج على التوقف حتى نهاية جميع const details = await Promise.all(promises) console.log("Process Finished); } اقتباس
0 Tamim Fahed نشر 3 مارس 2021 الكاتب أرسل تقرير نشر 3 مارس 2021 بتاريخ 49 دقائق مضت قال محمد أيت لعرايك: // pormises هنا يجب أن نجبر البرنامج على التوقف حتى نهاية جميع const details = await Promise.all(promises) مع تعديل الكود إلى هذا الشكل لم يتم التعرف على المتغيّر promises خارج الحلقة وظهر الخطأ التالي: promises is not defined اقتباس
0 Wael Aljamal نشر 3 مارس 2021 أرسل تقرير نشر 3 مارس 2021 بتاريخ 1 دقيقة مضت قال Tamim Fahed: مع تعديل الكود إلى هذا الشكل لم يتم التعرف على المتغيّر promises خارج الحلقة وظهر الخطأ التالي: promises is not defined نعم ما قصده المدرب محمد هو عمل مصفوفة بطول orders من الكائنات promesies وتمريرها للتابع Promise.all أي أولا يجب تهيئة المصفوفات ثم استدعائهم ومن ثم انتظار النتائج 1 اقتباس
0 محمد أيت لعرايك نشر 3 مارس 2021 أرسل تقرير نشر 3 مارس 2021 بتاريخ 9 دقائق مضت قال Tamim Fahed: مع تعديل الكود إلى هذا الشكل لم يتم التعرف على المتغيّر promises خارج الحلقة وظهر الخطأ التالي: promises is not defined انظر الكود جيدا promises معرفة في سطر const promises = await socket.on('getDetails' , async (response) => { console.log("order details:" + response); }) } اقتباس
0 Salah Eddin Beriani2 نشر 4 مارس 2021 أرسل تقرير نشر 4 مارس 2021 قم باستبدال for ...of جملة واحدة ب promise.all واستخدم map لتعمل حلقة حول orders وترجع قائمة ل promise.all وهي ستتكفل بالباقي exports.placeOrders = async (socket, orders) => { Promise.all( orders.map(async (order) => { console.log('Order ID: ' + order.id); socket.emit('requestOrderDetails', order.id); await socket.on('getDetails', async (response) => { console.log('order details:' + response); // await .. // await .. }); }) ); console.log('Process Finished'); }; اقتباس
السؤال
Tamim Fahed
استخدم node js من طرف السيرفر ولدي حلقة تقوم بإنشاء اتصال socket IO مع سيرفر آخر ويجب انتظار النتيجة ثم تنفيذ باقي التعليمات وتكرار الحلقة. ولكن ذلك لا يحصل.
هذا هو الكود:
exports.placeOrders = async (socket, orders) => { for await (order of orders){ console.log("Order ID: " + order.id); socket.emit('requestOrderDetails', order.id); await socket.on('getDetails' , async (response) => { console.log("order details:" + response); await .. await .. }) } console.log("Process Finished); }
الحلقة تقوم بالمرور على الطلبات orders وعند كل طلب تقوم بجلب باقي التفاصيل من السيرفر الآخر عن طريق socket.
ولكن بدلاً من الحصول على النتائج بالترتيب أحصل على التالي:
Order ID: Process Finished Order details: ولكن الترتيب الصحيح هو 1-order ID 2-order details 3-process finished
حاولت استخدام for await وأيضاً حلقة for العادية ولكن نفس النتيجة. ما الحل؟
تم التعديل في بواسطة Tamim Fahed6 أجوبة على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.