【发布时间】:2016-07-30 20:09:50
【问题描述】:
我想遍历一组学生并为每个学生进行 http 调用并解析响应并插入到 mongodb 中,所以我想为每个学生一个接一个地执行此操作,直到插入所有数据然后继续下一个,这样对 CPU 和 RAM 内存会更好...
到目前为止,我正在这样做,但由于某种原因,这不是我想要的......
var startDate = new Date("February 20, 2016 00:00:00"); //Start from February
var from = new Date(startDate).getTime() / 1000;
startDate.setDate(startDate.getDate() + 30);
var to = new Date(startDate).getTime() / 1000;
iterateThruAllStudents(from, to);
function iterateThruAllStudents(from, to) {
Student.find({status: 'student'})
.populate('user')
.exec(function (err, students) {
if (err) {
throw err;
}
async.eachSeries(students, function iteratee(student, callback) {
if (student.worksnap.user != null) {
var worksnapOptions = {
hostname: 'worksnaps.com',
path: '/api/projects/' + project_id + '/time_entries.xml?user_ids=' + student.worksnap.user.user_id + '&from_timestamp=' + from + '&to_timestamp=' + to,
headers: {
'Authorization': 'Basic xxx='
},
method: 'GET'
};
promisedRequest(worksnapOptions)
.then(function (response) { //callback invoked on deferred.resolve
parser.parseString(response, 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);
});
});
callback(null);
});
}, function (newsError) { //callback invoked on deferred.reject
console.log(newsError);
});
}
});
});
}
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(Math.random());
}
});
});
}
function promisedRequest(requestOptions) {
//create a deferred object from Q
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var deferred = Q.defer();
var req = http.request(requestOptions, function (response) {
//set the response encoding to parse json string
response.setEncoding('utf8');
var responseData = '';
//append data to responseData variable on the 'data' event emission
response.on('data', function (data) {
responseData += data;
});
//listen to the 'end' event
response.on('end', function () {
//resolve the deferred object with the response
console.log('http call finished');
deferred.resolve(responseData);
});
});
//listen to the 'error' event
req.on('error', function (err) {
//if an error occurs reject the deferred
deferred.reject(err);
});
req.end();
//we are returning a promise object
//if we returned the deferred object
//deferred object reject and resolve could potentially be modified
//violating the expected behavior of this function
return deferred.promise;
}
.then 中的 saveEntry() 似乎同时被所有学生调用,这似乎有问题。
我是 Javascript 新手,尤其是在涉及承诺、回调时... 任何人都知道实现这样的事情......
【问题讨论】:
-
什么是
parser.parseString()?这是同步操作还是异步操作? -
另外,你应该知道在异步回调中使用
throw绝对没有好处,除非它在promise.then()处理程序中。它只是回到异步操作的内部,你永远无法在任何地方捕捉到它。在这种情况下不要使用 throw。 -
另外,为什么
_.forEach(timeEntry)?那时timeEntry是什么? -
@jfriend00 parser.parseString() 我不知道它是异步的还是同步的,我不得不用它来解析 xml...似乎异步...你知道我是否可以添加然后() 到那里,所以我可以在那里添加 saveTimeEntry() ?
标签: javascript node.js promise q