Reputation: 23
I'm working in my own rss reader using JS, JQuery and PHP for serving the data as JSON. What I'm doing basically is making async calls to my server to get JSONs with the posts, then on 'success' I parse them using a '$.each' and with JQuery load the content in the DOM. All of this operations were made async, but now I need to call them in a certain order, and when everithin is done THEN calling a function to process the data. To give you some background on my task, what I'm doing is a query over a small list of RSS sources to get just the very latest post. With them I concat a string and this string is passed to a text-to-speech service. I've managed to make it work using an arbitrary setTimeout value of 10 seconds, but my goal is to call the function when all the sources have been processed.
This is a basic version of my parser:
function urgent_posts(url) {
$.ajax({
//the location of my server
url: 'myPostServer.php?url=' + encodeURIComponent(url),
dataType: 'json',
success: function(data) {
//do this for each entry in the feed
$.each(data.feed.entries, function(key, value) {
//validate the date to get just the latest post
if (is_urgent(value.publishedDate)) {
//if condition is met save the title
save_urgent_post_title(value.title);
}
});
}
});
}
What I did to 'make it work' was the following:
$('#test_button').on('click',function(){
urgent_posts(source_1);
urgent_posts(source_2);
urgent_posts(source_3);
//and so on...
urgent_posts(source_n);
setTimeout(function(){
text_to_speech(get_urgent_post_string);
},10000);
});
I tried with no result to make use of the deferred object y JQuery like this:
function urgent_posts(url) {
var deferred = $.Deferred();
$.ajax({
//the location of my server
url: 'myPostServer.php?url=' + encodeURIComponent(url),
dataType: 'json',
success: function(data) {
//do this for each entry in the feed
$.each(data.feed.entries, function(key, value) {
//validate the date to get just the latest post
if (is_urgent(value.publishedDate)) {
//if condition is met save the title
save_urgent_post_title(value.title);
}
});
}
});
return deferred.promise();
}
And chaining everything together:
$('#test_button').on('click',function(){
urgent_posts(source_1)
.then(urgent_posts(source_2))
.then(urgent_posts(source_3))
.then(function(){
text_to_speech(get_urgent_post_string);
});
});
I'd apreciatte your comments and suggestions.
Upvotes: 0
Views: 70
Reputation: 23
I manage to solve the problem using this article: link
The refactored code looks like this now:
function urgent_posts_feed_1(callback) {
return $.ajax({
//the location of my server
url: 'myPostServer.php?url=' + encodeURIComponent(feed_1),
dataType: 'json',
success: function(data) {
//do this for each entry in the feed
$.each(data.feed.entries, function(key, value) {
//validate the date to get just the latest post
if (is_urgent(value.publishedDate)) {
//if condition is met save the title
save_urgent_post_title(value.title);
}
});
}
});
}
I repeat myself (I know it's not cool to do so) and write the following functions manually setting the url:
urgent_posts_feed_2 urgent_posts_feed_3 urgent_posts_feed_4 ... urgent_posts_feed_n
And finally...
urgent_post_feed_1()
.then(urgent_post_feed_2)
.then(urgent_post_feed_3)
//...
.then(urgent_post_feed_n)
.then(function(){
text_to_speech(get_urgent_post_string);
});
This way it works like a charm. Now I have to figure out how to pass parameters to the function and not interfer with the callback.
Upvotes: 0
Reputation: 15104
First, your deferred object is never resolved. You have to add the deferred.resolve()
somewhere. Just after the $.each
loop looks like a nice place.
Second, $.ajax
already returns a promise. So you can just write this :
return $.ajax({
//the location of my server
url: 'myPostServer.php?url=' + encodeURIComponent(url),
dataType: 'json',
success: function(data) {
//do this for each entry in the feed
$.each(data.feed.entries, function(key, value) {
//validate the date to get just the latest post
if (is_urgent(value.publishedDate)) {
//if condition is met save the title
save_urgent_post_title(value.title);
}
});
}
});
Upvotes: 3