我有一个电话:
var serve = function(teacher, callback) {
RE.createFakeMemberData(function(err, avgMember) {
//omitted
});
};
在createFakeMemberData
内,如果我尝试实例化一个猫鼬模型:
var statistic = new Statistic();
我收到堆栈跟踪的错误:
D:\Orkun\workspace\teb\tebesir-repo\scripts\engines\ResetEngine.js:61
var statistic = new Statistic();
^
TypeError: object is not a function
at Object.createFakeMemberData (D:\Orkun\workspace\teb\tebesir-repo\scripts\engines\ResetEngine.js:61:21)
at Promise.<anonymous> (D:\Orkun\workspace\teb\tebesir-repo\scripts\servlets\graph\ServeSpider-Teacher.js:29:20)
at Promise.<anonymous> (D:\Orkun\workspace\teb\tebesir-repo\node_modules\mongoose\node_modules\mpromise\lib\promise.js:177:8)
at Promise.emit (events.js:95:17)
我认为'this'
超出范围或某事。我也尝试过使用bind
..
RE.createFakeMemberData(function(err, avgMember) {
//omitted
}).bind(this);
没有快乐..
编辑:统计
// external libs that are going to be used
var bunyan = require('bunyan');
var mongoose = require('mongoose');
var _ = require('underscore');
var Schema = mongoose.Schema;
// models that are going to be used
var Subject = require('../../scripts/models/Subject');
var CF = require('../../scripts/utilities/CommonFunctions');
var ResetEngine = require('../engines/ResetEngine');
var MetricEngine = require('../engines/MetricEngine');
var Constants = require('../../scripts/utilities/Constants');
var log = bunyan.createLogger({src: true, name: 'logStatistics'});
var Statistic = new Schema(
{
solved_tot: {type: Number, default : 0}, // number
score_tot: {type: Number, default : 0}, // score
time_tot: {type: Number, default : 0}, // time
// statistics for all the subjects available to the client
stats: [{
stat_id: { type: String, required: true},
stat_name: { type: String, required: true},
stat_solved: { type: Number, default : 0},
stat_score: { type: Number, default : 0},
stat_time: { type: Number, default : 0}
}]
}, { strict: true });
// !param new_score the book that has been bought as Book
// !param new_time of the user which makes the buy as String
// !param test_solved the book that has been bought as Book
// !desc should be async for extra performance opt
Statistic.methods.updateStatisticsFromTest = function(test_solved, new_time, new_score, callback) {
for (var i = 0; i < test_solved.subjects.length; i++) {
for (var k = 0; k < this.stats.length; ++k) {
if (test_solved.subjects[i].subject_name == this.stats[k].stat_name) {
// set the current variables
var current_score = this.stats[k].stat_score;
var current_time = this.stats[k].stat_time;
var current_solved = this.stats[k].stat_solved;
// calculate and update three indexes
this.stats[k].stat_score = (((current_score * current_solved) + new_score) / (current_solved + 1)).toFixed(5);
this.stats[k].stat_time = (((current_time * current_solved) + new_time) / (current_solved + 1)).toFixed(5);
this.stats[k].stat_solved++;
break;
}
}
}
// calculate the average total time
this.time_tot = (((this.time_tot * this.solved_tot) + new_time) / (this.solved_tot + 1)).toFixed(5);
// calculate the average score
this.score_tot = (((this.score_tot * this.solved_tot) + new_score) / (this.solved_tot + 1)).toFixed(5);
// increase the number of tests solved
this.solved_tot++;
// save the new user stat
this.save(function(err) {
if (CF.errorCheck(err, Constants.DB_ERROR, 'save Statistic')) return callback(err);
return callback(null, this);
});
};
// !brief creates an empty subject statistics object for a new user
// !param subjectList (Array<Subject>) list of subjects that will be included to the statistics
// !callback function that will be called when the database query ends
Statistic.methods.createStatistics = function(subjectList) {
// initialize and add all the subjects to the statistics object
this.stats = [];
for (var i = 0; i < subjectList.length; i++) {
this.stats.push({'stat_id': subjectList[i].id.toString(), 'stat_name' : subjectList[i].name});
}
};
// !brief aggregates the subject statistics on a single topic statistics
// !param subjectStatisticsObjectList ( Array <Statistic> ) subject statistics to be aggregated
Statistic.methods.aggregateStatistic = function(statisticsObjectList) {
ResetEngine.resetStatistic(this);
for (var i = 0; i < statisticsObjectList.length; i++) {
this.solved_tot += statisticsObjectList[i].solved_tot;
this.time_tot += statisticsObjectList[i].time_tot;
this.score_tot += statisticsObjectList[i].score_tot * statisticsObjectList[i].solved_tot;
for (var k = 0; k < statisticsObjectList[i].stats.length; k++) {
this.stats[k].stat_solved += statisticsObjectList[i].stats[k].stat_solved;
this.stats[k].stat_score += statisticsObjectList[i].stats[k].stat_score / statisticsObjectList.length;
this.stats[k].stat_time += statisticsObjectList[i].stats[k].stat_time;
this.stats[k].subject_watch += statisticsObjectList[i].stats[k].subject_watch;
}
}
this.score_tot = this.score_tot / statisticsObjectList.length;
ResetEngine.roundStatistic(this);
};
// !brief gets the topic statistics in the this object which belong to a subject
// !param theSubject ( Subject ) subject that we are going to search for
// !param topicList ( Array<Topic> ) topic lists that is going to be searched
// !return (Array<Topic>) test that are found by the function
Statistic.methods.getTopicStatBlobBySubject = function(subjectObject, topicList) {
var TopicStatisticsOfSubject = [];
for (var i = 0; i < topicList.length; i++) {
if (topicList[i].subject === subjectObject._id.toString()) {
for (var k = 0; k < this.stats.length; k++) {
if (this.stats[k].stat_id === topicList[i]._id.toString()) {
TopicStatisticsOfSubject.push(this.stats[k]);
break;
}
}
}
}
return TopicStatisticsOfSubject;
};
// !brief find the blob that belongs to the given subject or topic name
// !param statName ( String ) the name of the subject or topic that blob will be found
// !return subjectBlob or topicBlob (Statistic.stats)
Statistic.methods.getStatBlob = function(statName) {
for (var i = 0; i < this.stats.length; i++) {
if (this.stats[i].stat_name === statName) {
return this.stats[i];
}
}
};
module.exports = mongoose.model('Statistic' , Statistic);