كيف يمكنني انتظار الأحداث غير المتزامنة في Javascript؟
-
20-12-2019 - |
سؤال
أنا جديد على JavaScript، وما زلت غير معتاد على الوظائف غير المتزامنة...
أنا أعمل مع Node.js لإنشاء خادم دردشة، وهذا جزء من الكود الذي أستمع إليه getListConnected
الحدث وعندما يتم تشغيله، ابحث عن كل ما هو متصل clients
في مساحة اسم معينة، ثم أقوم بتخزين "اسم المستخدم" الخاص به لكل عميل في صفيف آخر، وتحويله إلى استجابة json ثم إرسال:
socket.on('getListConnected', function(msg){
var clients = namespace.clients();//get all client in that nsp
var usernames = Array() ;//init array
for(i in clients)//for each clients
{
clients[i].get("username", function(value){
usernames.push(value);
});
}
socket.emit('getListConnected',JSON.stringify(usernames));//send
});
المشكلة في هذا الرمز هي أن طريقة Client.get() غير متزامنة وتعني أنه يتم إرسال أسماء المستخدمين فارغة.
كيف يمكنني انتظار أسماء المستخدمين حتى يتم ملؤها، أو كيف يمكنني انتظار الحلقة حتى تنتهي؟
المحلول
يمكنك استخدام البرامج الوسيطة للوعود، شيء من هذا القبيل طائر أزرق, ، أو يمكنك الاحتفاظ بعداد للتحقق مما إذا تم الحصول على جميع أسماء المستخدمين، مثل
socket.on('getListConnected', function (msg) {
var clients = namespace.clients();
var usernames = [];
var counter1 = 0;
var counter2 = 0;
for (i in clients) {
counter1++; // number of clients
clients[i].get("username", function (value) {
usernames.push(value);
counter2++; // number of clients added to array
if (counter1 === counter2) {
socket.emit('getListConnected', JSON.stringify(usernames));
}
});
}
});
نصائح أخرى
إليك مثال بلوبيرد، المخصص لموقفك:[يقترض بشدة من مثال فيكتور كوين]
باستخدام نفس تعريف الوعد الذي استخدمه فيكتور:
var Promise = require('bluebird');
var promiseWhile = function(condition, action) {
var resolver = Promise.defer();
var loop = function() {
if (!condition()) return resolver.resolve();
return Promise.cast(action())
.then(loop)
.catch(resolver.reject);
};
process.nextTick(loop);
return resolver.promise;
};
تم إنشاء مثيل لمكالمتك المخصصة:
var i = 0;
promiseWhile(function() {
return i < clients.length;
}, function(value) {
return new Promise(function(resolve, reject) {
clients[i].get("username", function(value){
usernames.push(value);
});
i++;
resolve();
});
}).then(function() {
console.log("usernames are: " + usernames);
});