I am struggling a little with how to call asynchronous functions in a serial manner. In particular, functions which incorporate mongoose calls to the database. I have a class definition which includes two methods: (MovieFile.exists) checks if a certain record exists in the database; (MovieFile.save) saves a record in the database. Ideally I want to be able to save the record (MovieFile.save()) after confirming whether or not it exists in the database (MovieFile.exists()).
Ideally I want to do something like this:
// Create instance of MovieFile object.
var movieFile = new MovieFile(mongoose);
if (movieFile.exists() === false) {
movieFile.save();
}
Unfortunately the asynchronous nature on mongoose makes this not possible. I have been playing around with Step and Async control flow frameworks. Unfortunately I just can't get my head around how to use such frameworks in this case. I would be grateful if someone could tell me how to put the above code into either Step or Async. I think the issue is that the asynchronous mongoose calls are themselves embedded within a method (See: MovieFile.exists and MovieFile.save). I realise that use of such a framework may be overkill in this example, but I am trying to use this as a learning exercise.
function MovieFile(mongoose) {
var Movie = mongoose.model('Movie');
this.exists = function() {
// Confirm necessary object variables have been set.
if (typeof this.originalFileName === 'undefined') {
throw error = new Error('Variable originalFilename has not been set for MovieFile.');
}
if (typeof this.fileSize !== 'number') {
throw error = new Error('Variable originalFilename has not been set for MovieFile.');
}
// Check database for existing record.
Movie
.find({ originalFileName: this.originalFileName, size: this.fileSize })
.exec(function(error, results) {
if (error) {
throw error;
}
else if (results.length === 0) {
return false;
}
else if (results.length === 1) {
return true;
}
else {
throw error = new Error('More than one record for this movie record exists.');
}
});
};
this.save = function() {
// save movie to database.
var values = {
name: this.getName(),
machineFileName: this.getMachineFileName(),
originalFileName: this.getName(),
size: this.getFileSize(),
};
var movie = new Movie(values);
movie.save(function(error, data) {
if (error) {
console.log(error);
}
else {
console.log('Movie saved.');
}
});
};
};