问题
I have a problem with inserting data to mongo db using node(express)
My code looks like this:
router.get('/data/:section/:sort', function(req, res, next) {
//Deleting old data always before writing new
//Image.remove().exec();
var section = req.params.section;
var sort = req.params.sort;
//Link to Igmur API
var url = 'https://api.imgur.com/3/gallery/'+section+'/'+sort+'/1'; //1 at the end is used to get more than 60 images(gives only 60 without it)
request.get({
url: url,
method: 'GET',
headers: {
'Authorization': 'Client-Id XXXXXXXXXXXXX'
}}, function(e, r, body){
var metadata = JSON.parse(body);
for(var i = 0; i<100; i++){
var image = new Image(metadata.data[i])
image.save(function(err, result){
});
};res.render('index', { title: 'SearchAPI' });});});
The problem is that I get only about 20 objects inserted instead of 100 as u can see in the loop. All because node just jump forward before the save method is completely done. How can I fix this? Thank you in advance
回答1:
Use a promise library such as Q
What you basically need to do is wait for all your save
methods to complete. Use the Q.all
method which waits for everything to be executed.
var Q = require('q');
var promiseArr = [];
for(var i = 0; i<100; i++){
var imgDefer = Q.defer();
var image = new Image(metadata.data[i])
image.save(function(err, result){
if(err)imgDefer.reject(err);
else imgDefer.resolve()
});
promiseArr.push(imgDefer);
}
Q.all(promiseArr).then (function (){
res.render('index', { title: 'SearchAPI' });
})
回答2:
Calling the database again and again is a wrong practice it's better if you use create
and pass everything at once. Have a look at the snippet below. Hope it helps.
router.get('/data/:section/:sort', function(req, res, next) {
//Deleting old data always before writing new
//Image.remove().exec();
var section = req.params.section;
var sort = req.params.sort;
//Link to Igmur API
var url = 'https://api.imgur.com/3/gallery/'+section+'/'+sort+'/1'; //1 at the end is used to get more than 60 images(gives only 60 without it)
request.get({
url: url,
method: 'GET',
headers: {
'Authorization': 'Client-Id XXXXXXXXXXXXX'
}}, function(e, r, body){
var metadata = JSON.parse(body);
Image.create(metadata.data,(err, result)=>{
//do operations here
res.render('index', { title: 'SearchAPI' });
})
/* WRONG PRACTICE */
// for(var i = 0; i<100; i++){
// var image = new Image(metadata.data[i])
// image.save(function(err, result){
// });
// };
});
});
来源:https://stackoverflow.com/questions/40191639/how-to-insert-data-to-mongo-synchronously-nodejs-express