【问题标题】:insert data into array from redis inside a foreach in node js在节点js中的foreach内将数据从redis插入数组
【发布时间】:2016-10-04 18:12:42
【问题描述】:

我有一个节点 js redis api,我在其中根据 key 从 redis 读取数据,如果不存在,则从另一个 api 获取它,然后将此数据插入 redis。我还将这些数据推送到一个变量中,并在 foreach 结束时将此值返回给最终用户。

问题是 redis 以异步方式运行,因此我的数据变量始终为空。我该如何解决这个问题?

这是我的代码的相关部分

   between.forEach(function(entry) {

    asyncTasks.push(function(callback){

        client.exists(id+entry, function(err, reply) {
            if (reply === 1) {
                client.get(id+entry, function(err, reply) {
                    var output = JSON.parse(reply);
                    data_output = data_output.concat(output);
                });
            } else {
                process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
                var slot_url = "https://" + username + ":" + password + "@testapi.foobar.com/1/timeslots?productId=" + id + "&fromDate=" + entry + "&toDate=" + entry;
                request({

                    url: slot_url,
                    json: true,
                    headers: headers
                }, function(error, response, body) {
                    if (!error && response.statusCode === 200) {
                        var data = [];
                        try {
                            var temp = {};
                            console.log(body);
                            body.data.forEach(function(tempslots) {
                                temp['date'] = tempslots['date'];
                                temp['timeslots'] = tempslots['timeslots'];
                                data = data.concat(temp);
                            });
                            client.set(id+entry, JSON.stringify(data));
                            data_output = data_output.concat(data);
                        } catch (err) {
                            console.log(err.message);
                        }
                    } else {
                        console.log("Something went wrong!! " + error.message);
                    }
                })
            }
            callback();
        });
    });

});

async.parallel(asyncTasks, function(){
    // All tasks are done now
    result['data'] = data_output;
    result['response'] = 1;
    result['message'] = 'vacancies list fetched successfully!';
    res.json(result);
});

});

输出总是像这样{"data":[],"response":1,"message":"Capacity list fetched successfully!"} 即使我检查了代码是否正确地在redis中获取和插入数据

【问题讨论】:

  • 我们知道node js async所以你的foreach首先工作然后你的radis数据将被设置。所以数据输出是空的
  • @HimanshuGoyal 我已经知道了,我什至使用 async.parallel 来摆脱这个问题,但它仍然无法工作。如果可能,请给出解决方案
  • 我想了很多关于你的代码,我发现你可以使用递归函数,我总是使用递归函数来防止这个问题
  • 我为你写代码可能会有所帮助

标签: node.js foreach node-redis


【解决方案1】:
var totalLengthOfItem = between.length;
for (var i = 0; i < totalLengthOfItem - 1; i++) {
    var entry = between[i];
    client.exists(id + entry, function (err, reply) {
        if (reply === 1) {
            client.get(id + entry, function (err, reply) {
                var output = JSON.parse(reply);
                data_output = data_output.concat(output);
                if (i == totalLengthOfItem - 1) {
                    response(data_output);
                }
            });
        } else {
            process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
            var slot_url = "https://" + username + ":" + password + "@testapi.foobar.com/1/timeslots?productId=" + id + "&fromDate=" + entry + "&toDate=" + entry;
            request({

                url: slot_url,
                json: true,
                headers: headers
            }, function (error, response, body) {
                if (!error && response.statusCode === 200) {
                    var data = [];
                    try {
                        var temp = {};
                        body.data.forEach(function (tempslots) {
                            temp['date'] = tempslots['date'];
                            temp['timeslots'] = tempslots['timeslots'];
                            data = data.concat(temp);
                        });
                        client.set(id + entry, JSON.stringify(data));
                        data_output = data_output.concat(data);
                        if (i == totalLengthOfItem - 1) {
                            response(data_output);
                        }
                    } catch (err) {
                        console.log(err.message);
                    }
                } else {
                    console.log("Something went wrong!! " + error.message);
                }
            })
        }
    });

}

function response(data_output) {
    result['data'] = data_output;
    result['response'] = 1;
    result['message'] = 'Capacity list fetched successfully!';
    res.json(result);
}
})

【讨论】:

  • 不会工作@HimanshuGoyal 我收到错误,cant send header after they are sent 意味着您的函数响应被多次调用
  • 您只需使用 console.log bcz 进行跟踪,我没有对其进行测试,但我认为响应是调用一次。
  • 不会被多次调用,每次循环运行时,我都在研究它,但我认为这样做的好方法是使用异步
猜你喜欢
  • 2018-08-03
  • 2019-12-23
  • 2021-07-02
  • 2018-12-29
  • 1970-01-01
  • 2021-11-12
  • 2018-03-09
  • 2018-05-11
  • 1970-01-01
相关资源
最近更新 更多