在nodejs中有奇怪的每个行为

时间:2016-10-03 13:01:55

标签: node.js foreach node-redis

我正在创建一个nodejs和redis API服务,我编写了下面的代码来查找日期范围内的各个日期,然后获取每个日期的时间段并将其存储在redis中。

问题是我在forEach中执行console.log("Keys :"+key)并检查同一forEach中的键,但由于某种原因,循环分别执行单个函数。

我附加代码和控制台输出以更好地解释问题

//API to get slot for a particular date range
app.get('/listcapacity/:ticketid/:fromdate/:todate', function(req, res) {
    var id = req.params.ticketid;
    var fromdate = req.params.fromdate;
    var todate = req.params.todate;
    var key = null;
    var username = 'foo';
    var password = 'foobar';
    var result = {};
    var data_output = [];
    var currentDate = new Date(fromdate);
    var between = [];
    var end = new Date(todate);

    while (currentDate <= end) {
        var tempdate = new Date(currentDate).toISOString();
        var dump = tempdate.toString().split("T");
        between.push(dump[0]);
        currentDate.setDate(currentDate.getDate() + 1);
    }

    between.forEach(function(entry) {
        key = id+entry+"list";
        console.log("Keys: " + key);
        client.exists(key, function(err, reply) {
            if (reply === 1) {
                console.log("Key : " + key + " Found");
                client.get(key, function(err, reply) {
                    var output = JSON.parse(reply);
                    data_output = data_output.concat(output);
                });
            } else {
                console.log("Key : " + key + " Not Found");

                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(key, JSON.stringify(data));
                            data_output = data_output.concat(data);
                        } catch (err) {

                            console.log(err.message);

                        }
                    } else {
                        console.log("Something went wrong!! " + error.message);
                    }
                })
            }
        });
    });
    result['data'] = data_output;
    result['response'] = 1;
    result['message'] = 'Capacity list fetched successfully!';
    res.json(result);

});

这是控制台输出

Keys: 5212016-10-01list
Keys: 5212016-10-02list
Keys: 5212016-10-03list
Keys: 5212016-10-04list
Keys: 5212016-10-05list
Key : 5212016-10-05list Not Found
Key : 5212016-10-05list Not Found
Key : 5212016-10-05list Not Found
Key : 5212016-10-05list Not Found
Key : 5212016-10-05list Found

正如你可以看到使用redis检查时的键值只是获取最后一个值,因为在我定义键时它位于同一个循环中,它具有正确的值,就像在控制台中打印一样

1 个答案:

答案 0 :(得分:1)

问题是redis操作是异步的。所以回调将在下一个tick中执行。所以到那时关键变量是最后一个变量。

您应该使用局部变量。