Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Javascript中等待异步事件?_Javascript_Node.js_Socket.io_Dom Events_Event Driven - Fatal编程技术网

如何在Javascript中等待异步事件?

如何在Javascript中等待异步事件?,javascript,node.js,socket.io,dom-events,event-driven,Javascript,Node.js,Socket.io,Dom Events,Event Driven,我是JavaScript新手,仍然不熟悉异步函数 我正在使用node.js创建一个聊天服务器,这是我代码的一部分,它是侦听getListConnected事件,当它触发时,在给定名称空间中查找所有连接的客户端,然后将每个客户端的“用户名”存储到另一个数组中,将其转换为JSON响应,然后发送: socket.on('getListConnected', function(msg){ var clients = namespace.clients();

我是JavaScript新手,仍然不熟悉异步函数

我正在使用node.js创建一个聊天服务器,这是我代码的一部分,它是侦听
getListConnected
事件,当它触发时,在给定名称空间中查找所有连接的
客户端
,然后将每个客户端的“用户名”存储到另一个数组中,将其转换为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));
            }

        });
    }

});

下面是一个针对您的情况定制的蓝鸟示例: [它大量借款于]

使用Victor使用的相同承诺定义:

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);
});
var i=0;
允诺人(职能){
返回i
thx,我将浏览蓝鸟,但在您的代码中不正常,每当c1=c2时,这会多次发送数组。。。但是有不同的想法是可以的!再次感谢!但是c1什么时候和c2一样,除了每个用户名都被获取。循环立即完成对第一个计数器的计数,当第一个计数器递增,然后递增第二个计数器时,async函数将在将来的某个时间完成。第一个计数器总是比异步计数器提前一步,所以它们唯一应该保持一致的时间是在最后。