Sto imparando nodo, express, mongo e, nel processo, javascript. Sto cercando di ottenere una funzione in cui utilizzare rssparser, ottenere un elenco di storie e salvarle in un database mongo con mangusta.Problemi durante l'iterazione della matrice e salvataggio in mangusta. Problema di richiamata?
Ho la funzione RSS che funziona, e sto scorrendo le storie, è il risparmio con cui sto avendo problemi. Voglio 1) controllare che la storia non sia già presente nel database, e 2) se no, salvarla. Penso di essermi perso nel modo in cui vengono gestite le callback. Ecco il mio codice attuale, con commenti.
rssparser.parseURL(url, options, function(err,out){
// out.items is an array of the items pulled
var items = out.items;
var story;
for (var i=0; i<items.length; i++){
//create a mongoose story
story = new schemas.Stories({
title: items[i].title,
url: items[i].url,
summary: items[i].summary,
published: items[i].published_at
});
//TODO: for testing - these show up correctly.
//If I pull 10 stories, I get 10 entries from here that match
//So "story" is holding the current story
console.log("items[i] is :" + items[i].title);
console.log("story title is : " + story.title);
// setup query to see if it's already in db
var query = schemas.Stories.findOne({
"title" : story.title,
"url" : story.url
});
//execute the query
query.exec(function(err, row){
if(err) console.log("error-query: " + err);
console.log("row: "+ row);
if(!row) {
// not there, so save
console.log('about to save story.title: ' + story.title);
story.save(function (err){
console.log("error in save: " + err);
});
}
});
}
});
Quando questo viene eseguito, quello che vedo è un sacco di output della console:
E 'inizia a mostrare tutte le storie (molti omesso):
items[i] is :TSA Drops Plan to Let Passengers Carry Small Knives on Planes
story title is : TSA Drops Plan to Let Passengers Carry Small Knives on Planes
items[i] is :BUILDING COLLAPSE:1 Reportedly Dead, 13 Pulled From Philly Rubble
story title is : BUILDING COLLAPSE:1 Reportedly Dead, 13 Pulled From Philly Rubble
items[i] is :CONTROVERSIAL PAST: Obama's UN Nominee Once Likened US 'Sins' to Nazis'
story title is : CONTROVERSIAL PAST: Obama's UN Nominee Once Likened US 'Sins' to Nazis'
items[i] is :WRITING OUT WRIGHTS: Bill Gives First Powered Flight Nod to Whitehead
story title is : WRITING OUT WRIGHTS: Bill Gives First Powered Flight Nod to Whitehead
items[i] is :BREAKING NEWS: Rice Named to Top Security Post Despite Libya Fallout
story title is : BREAKING NEWS: Rice Named to Top Security Post Despite Libya Fallout
Poi continua così (molti omesso):
row: null
about to save story.title: Best Ribs in America
row: null
about to save story.title: Best Ribs in America
row: null
about to save story.title: Best Ribs in America
row: null
about to save story.title: Best Ribs in America
row: null
about to save story.title: Best Ribs in America
row: null
about to save story.title: Best Ribs in America
row: { title: 'Best Ribs in America',
url: 'http://www.foxnews.com/leisure/2013/06/05/10-best-ribs-in-america/',
published: 1370463800000,
_id: 51af9f881995d40425000023,
__v: 0 }
Ripete il titolo "about to save" (che è l'ultimo articolo nel feed) e salva il storia una volta, come mostra l'ultima riga.
L'output console.log mostra solo che l'ho messo, tutto il titolo del titolo in uscita in alto, poi tutte le cose all'interno della query.exec() chiamata in basso.
Ogni aiuto è apprezzato ...
Ho implementato il metodo di pulizia e ha funzionato benissimo, grazie. Quindi il mio problema era solo un problema di temporizzazione? cioè, tutti gli elementi di out.items sono stati ripetuti prima che il callback fosse eseguito (quindi la trama è stata impostata sull'ultimo out.item)? – Mike
Il tuo problema ha avuto a che fare con l'ambito, che ha provocato una condizione di competizione. quando il ciclo for sta iterando, c'è solo un riferimento al 'story', ed è sovrascritto ogni volta che si itera su un array. Se la funzione exec venisse eseguita immediatamente, in modo sincrono, il tuo codice avrebbe funzionato bene, ma poiché tutte le chiamate al callback in exec si verificano dopo che il ciclo for è terminato, si riferiscono tutte all'ultima istanza della storia assegnata alla variabile storia. quando sono "chiusi" con una funzione, hanno tutti una propria istanza di "storia". questo è un errore molto comune – arnorhs