NODE.JS:致命错误 - JS分配失败 - 在解析大型json对象时处理内存不足

时间:2016-04-08 18:30:49

标签: javascript mongodb

我正在尝试解析并将一些来自API的数据添加到mongodb数据库中。我希望从特定时间到今天为每个用户获取所有数据。 所以我正在做的是,我每次迭代检索每个用户数据5天,所以它就像2-3个月的数据分成5天。

出于某种原因,我收到了Allocation Failer的错误 - 处理内存不足。

似乎我在到达特定用户时遇到此错误,因为他似乎比其他人有更多数据。

我在运行脚本时尝试过这个命令:node --max-old-space-size = 4028 worksnap.js。

我的代码如下所示:

var currentMonth = new Date();
    var startDate = new Date("February 1, 2016 00:00:00");  //Start from February

var counter = 1;
while (startDate.getMonth() <= currentMonth.getMonth()) {
    //todo:: look if u have to increaze the start time, due the previous end time becomes start time it can take the same time time entries (have to be reviewd and make sure)....
    var from = new Date(startDate).getTime() / 1000;
    startDate.setDate(startDate.getDate() + 5);
    var to = new Date(startDate).getTime() / 1000;
    iterateThruAllStudents(from, to);
} 

function getTimeEntriesFromWorksnap(error, response, body) {
        //console.log(response.statusCode);
        if (!error && response.statusCode == 200) {
            parser.parseString(body, function (err, results) {
                var json_string = JSON.stringify(results.time_entries);
                var timeEntries = JSON.parse(json_string);
                _.forEach(timeEntries, function (timeEntry) {
                    _.forEach(timeEntry, function (item) {
                        saveTimeEntry(item);
                    });
                });
            });
        }
    }

    function saveTimeEntry(item) {
        Student.findOne({
                'worksnap.user.user_id': item.user_id[0]
            })
            .populate('user')
            .exec(function (err, student) {
                if (err) {
                    throw err;
                }
                student.timeEntries.push(item);
                student.save(function (err) {
                    if (err) {
                        console.log(err);
                    } else {
                        console.log('item inserted...');
                    }
                });

            });
    }

    function iterateThruAllStudents(from, to) {
        Student.find({status: 'student'})
            .populate('user')
            .exec(function (err, students) {
                if (err) {
                    throw err;
                }

                _.forEach(students, function (student, i) {
                    if (student.worksnap.user != null) {
                        setTimeout(function () {
                            var options = {
                                url: 'https://api.worksnaps.com/api/projects/' + project_id + '/time_entries.xml?user_ids=' + student.worksnap.user.user_id + '&from_timestamp=' + from + '&to_timestamp=' + to,
                                headers: {
                                    'Authorization': 'Basic bGhNSVwJkVUFasSxx2loOFVyZkFyOENEZEsdxxxCdUlHdElWMHo0czo='
                                }
                            };
                            request(options, getTimeEntriesFromWorksnap);
                        }, 5000 * i);
                    }
                });
            });
    }

任何人都知道我在做错了什么?

1 个答案:

答案 0 :(得分:0)

这是一条评论,因为它不包含解决方案。

有两件事看起来像 fishy

一个问题是:

while (startDate.getMonth() <= currentMonth.getMonth()) {
  //todo:: look if u have to increaze the start time, due the previous end time becomes start time it can take the same time time entries (have to be reviewd and make sure)....
  var from = new Date(startDate).getTime() / 1000;
  startDate.setDate(startDate.getDate() + 5);
  var to = new Date(startDate).getTime() / 1000;
  iterateThruAllStudents(from, to);
} 

您不要等到处理一名学生的数据,而是同时请求所有学生的数据。

类似的问题是setTimeout,因为根据执行时间,您的代码需要在内存中保存多个请求的数据。

你应该使用像async或Promise这样的东西来解决异步循环。