问题
I am making a newsreader app and using Parse.com background jobs to collect links from RSS feed of the newspaper. I have used xmlreader.js and sax.js to parse the httpResponse and using saveAll and beforeSave, periodically update the classes in data browser.
I have multiple newspapers with multiple categories making a total of more than 30 pairs, (I would have to later include more pair as I would like to include regional newspapers). Till now I was working with one newspaper and one category - The Hindu, sports category; and it is now working fine. Making copies of these two function and create jobs wont be efficient I think.
Therefore, I wanted to ask if I can convert both these jobs and beforeSave into some kind of function so that I can just pass in either newspaper-category pair class name or its url to do the stuff automatically.
Full Code - main.js
job -
Parse.Cloud.job("job_hindu_sports", function (request, response) {
return Parse.Cloud.httpRequest({
url: 'http://www.thehindu.com/sport/?service=rss'
}).then(function(httpResponse) {
var someXml = httpResponse.text;
xmlreader.read(someXml, function (err, res){
if(err) {
response.error("Error " +err);
return console.log(err);
}
var listArray = [];
res.rss.channel.item.each(function (i, item){
var hinduSports = new HinduSports(); //@startswithaj - this part
hinduSports.set("link", item.link.text());
hinduSports.set("title", item.title.text());
hinduSports.set("pubDate", item.pubDate.text());
//console.log("pubDate - "+ item.pubDate.text());
listArray.push(hinduSports);
});
var promises = [];
Parse.Object.saveAll(listArray, {
success: function(objs) {
promises.push(objs);
console.log("SAVED ALL!");
},
error: function(error) {
console.log("ERROR WHILE SAVING - "+error);
}
});
return Parse.Promise.when(promises);
});
}).then(function() {
response.success("Saving completed successfully.");
},function(error) {
response.error("Uh oh, something went wrong.");
});
});
beforeSave -
Parse.Cloud.beforeSave("HinduSports", function(request, response) {
//console.log("in beforeSave");
var query = new Parse.Query(HinduSports);
var linkText = request.object.get("link")
var titleText = request.object.get("title");
query.equalTo("link", linkText);
query.first({
success: function(object) {
//console.log("in query");
if (object) {
//console.log("found");
if(object.get('title')!==titleText){
console.log("title not same");
object.set("title", titleText);
response.success();
}
else{
console.log("title same");
response.error();
}
} else {
console.log("not found");
response.success();
}
},
error: function(error) {
response.error();
}
});
});
回答1:
In your job code you could query your datastore for all of the URLS you want to process, and then iterate through the results requesting each url and passing the httpresponse to a function that does all the work
So you would have (pseudo code)
function getDataForNewspaper(id, url){
return (function(id) {
Parse.Cloud.httpRequest({
url: url
}).then(function(httpResponse){
processDataForNewspaper(id, httpResponse)
})
})(id) //you need to have this in a closure so you can pass id to processDataFor...
function processDataforNewpaper(id, httpResponse){
someXml = httpResponse.text
//process your xml here
}
Parse.Cloud.job("get_data_for_all_newspapers", function (request, response) {
var query = new Parse.Query("Get all the newspapers").find{
success: function(list){
for each newspaper in list then
getDataForNewspaper(newspaper.id, newspaper.url)
}
}
}
It's not the best explanation but I hope this helps
回答2:
With the help from @startswithaj I modified my code to save all the articles in one class. The only thing left is to add a beforeSave
method. But there is still a problem. saveAll
gets completed only sometimes. For eg. I ran the code first time and got this in log :
I2014-04-26T18:18:40.036Z] v93: Ran job job_get_data_for_all_newspapers with:
Input: {}
Result: Saving completed successfully.
I2014-04-26T18:18:40.926Z] Successfully retrieved 2
I2014-04-26T18:18:40.926Z] getData NEW & CAT ID - 1, 5 feedUrl http://www.thehindu.com/sport/?service=rss
I2014-04-26T18:18:40.927Z] getData NEW & CAT ID - 1, 4 feedUrl http://www.thehindu.com/news/national/?service=rss
I2014-04-26T18:18:40.927Z] promisesGetNP [object Object],[object Object]
I2014-04-26T18:18:41.479Z] processData NEW & CAT ID - 1, 5
I2014-04-26T18:18:41.622Z] listArray http://www.thehindu.com/sport/other-sports/mankirat-singh-sets-record/article5951540.ece?utm_source=RSS_Feed&utm_medium=RSS&utm_campaign=RSS_Syndication
I2014-04-26T18:18:41.628Z] promises undefined
I2014-04-26T18:18:41.629Z] promisesGetData
I2014-04-26T18:18:41.629Z] Done getData?
I2014-04-26T18:18:42.082Z] processData NEW & CAT ID - 1, 4
I2014-04-26T18:18:42.311Z] listArray http://www.thehindu.com/news/national/muslim-women-entitled-to-maintenance-even-after-divorce-supreme-court/article5951562.ece?utm_source=RSS_Feed&utm_medium=RSS&utm_campaign=RSS_Syndication
I2014-04-26T18:18:42.324Z] promises undefined
I2014-04-26T18:18:42.324Z] promisesGetData
I2014-04-26T18:18:42.324Z] Done getData?
I2014-04-26T18:18:42.324Z] done job
and second time after deleting a few useless console.log I got this. You can see there is a SAVED ALL!
which is called in the success: function
of the saveAll
-
I2014-04-26T18:20:53.130Z] v94: Ran job job_get_data_for_all_newspapers with:
Input: {}
Result: Saving completed successfully.
I2014-04-26T18:20:53.307Z] Successfully retrieved 2
I2014-04-26T18:20:53.307Z] getData NEW & CAT ID - 1, 5 feedUrl http://www.thehindu.com/sport/?service=rss
I2014-04-26T18:20:53.307Z] getData NEW & CAT ID - 1, 4 feedUrl http://www.thehindu.com/news/national/?service=rss
I2014-04-26T18:20:53.911Z] processData NEW & CAT ID - 1, 5
I2014-04-26T18:20:53.951Z] listArray http://www.thehindu.com/sport/other-sports/mankirat-singh-sets-record/article5951540.ece?utm_source=RSS_Feed&utm_medium=RSS&utm_campaign=RSS_Syndication
I2014-04-26T18:20:53.995Z] Done getData?
I2014-04-26T18:20:54.200Z] SAVED ALL!
I2014-04-26T18:20:54.818Z] processData NEW & CAT ID - 1, 4
I2014-04-26T18:20:55.016Z] listArray http://www.thehindu.com/news/national/muslim-women-entitled-to-maintenance-even-after-divorce-supreme-court/article5951562.ece?utm_source=RSS_Feed&utm_medium=RSS&utm_campaign=RSS_Syndication
I2014-04-26T18:20:55.031Z] Done getData?
I2014-04-26T18:20:55.031Z] done job
My new code can be found here. The new code starts at Line 150.
来源:https://stackoverflow.com/questions/23309519/how-can-i-convert-background-jobs-to-something-like-functions