javascript - for 循环事件驱动代码?

标签 javascript asynchronous node.js event-driven event-driven-design

在 Redis 数据存储中,我有一个键列表,我想迭代该键列表并从 Redis 获取这些值。问题是我正在使用事件驱动语言,即通过 node.js 的 javascript

如果 javascript 是程序化的,我可以这样做

function getAll(callback) {
    var list = redis.lrange(lrange('mykey', 0, -1);
    for ( var i = 0; i < list.length; i+= 1 ) {
        list[i] = redis.hgetall(list[i]);
    }
    callback(list);
}

但是,我不能,因此..我这样做?

function getAll(callback) {
    redis.lrange('mykey', 0, -1, function(err, reply) {
        // convert reply into messages
        var list = [];
        var index = -1;
        var recurse = function() {
            if ( index == reply.length ) {
                callback(list);
            } else {
                redis.hgetall(reply[i], function(err, reply) {
                    list.push(reply);
                    index += 1;
                    recurse();
                });
            }
        };
        recurse()
    });
};

这似乎是错误的,因为我不是立即执行所有请求,然后让回调插入到列表中,而是强制执行顺序调用序列。如果有 1000 个 key 会发生什么?

我可以怎样做吗?

function getAll(callback) {
    redis.lrange('mykey', 0, -1, function(err, reply) {

        // convert reply into messages
        var list = [];
        var insert = function(err, reply) {
            list.push(reply);
        };
        for ( var i = 0; i < reply.length; i += 1 ) {
            redis.hgetall(reply[i], insert);
        }

        ??? how to block until finished ??? 
        callback(list);
    });
};

最佳答案

??? how to block until finished ???

如果您进行的调用是异步的,则不能。您必须定义您的 getAll 并期望它将异步完成,然后对其进行一些重新调整。

我不熟悉您正在进行的 redis 调用,但基本模式是:

function doTheBigThing(param, callbackWhenDone) {
    asyncCallToGetList(param, function(result) {
        var list = [];

        asyncCallToGetNextEntry(result.thingy, receivedNextEntry);

        function receivedNextEntry(nextResult) {
            if (nextResult.meansWeAreDone) {
                callback(list);
            }
            else {
                list.push(nextResult.info);
                asyncCallToGetNextEntry(result.thingy, receivedNextEntry);
            }
        }
    });
}

分解:

  1. doBigThing(您的getAll)被调用。
  2. 它执行“获取列表”调用,传入函数以在我们拥有列表或列表句柄或其他内容时用作回调。
  3. 该回调定义了一个函数 receivedNextEntry,并使用用于检索条目的任何信息调用“获取下一个条目”函数,并将其作为回调传入。
  4. receivedNextEntry 存储它获得的条目,如果完成,则触发主“全部完成”回调;如果没有,则发出下一个请求。

很抱歉无法为您提供特定于 Redis 的答案,但我认为映射是:

  • doBigThing = getAll
  • asyncCallToGetList = redis.lrange
  • asyncCallToGetNextEntry = redis.hgetall

...但是您使用 redis.lrangeredis.hgetall 的参数恐怕我不知道。

关于javascript - for 循环事件驱动代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4579999/

相关文章:

javascript - 动态创建的元素上的事件绑定(bind)?

javascript - 需要 IE 垫片的 Angular 5 和 IE11 问题

javascript - 为什么我的 JavaScript 回调不能用于异步结果?

javascript - Nodeschool learnyounode 过滤器 LS 练习 : Cannot read property 'toString' of undefined

node.js - 我需要 Live 服务器上的 "node_modules"文件夹吗

javascript - 使用脚本从客户端发送http post并在NODEJS中获取请求

javascript - jquery tablesorter 不适用于输入/选择字段 (IE8),适用于 IE8 中的所有其他文本字段

javascript - 为什么 'await'不等待?

javascript - 基于 Angular 中的 promise 结果取消间隔

javascript - Sequelize-auto 无法连接到命名的 MSSQL 实例