0

So I have a 'for' that on each iteration calls a different ajax call, in the callback of each call I collect some urls and run an ajax call for each url.

It looks something like this

for(var i=1; i<num_pages + 1; i++)
{

    var page_url = main_url + "&sf=" + i;

    console.log('=== doing page: ' + page_url);

    try
    {
        $.ajax({url: page_url, async:false, success: function(data) 
        { 
            var urls = [];

            $('a', data).each(function()
            {
                if($(this).attr('itemprop') == 'url')
                {
                    var u = $(this).attr('href');
                    if(urls.indexOf(u) == -1)
                    {
                        urls.push(u);
                    }
                }
            });

            // for(var j=0; j<urls.length; j++)
            for(var j=0; j<3; j++)
            {
                doSetTimeout(j, i);
            }
        }

        });
    }
    catch(err)
    {

    }
}

function doSetTimeout(i, page_num) 
{
  setTimeout(function() 
  { 
    get_info(urls[i], page_num);
  }, 100);
}

doSetTimeout() is used to have a delay of 100ms between calls to get_info(), get info is a a function containing an async ajax call.

I do them async to try to not overload the server with requests, and because I tried to find an order so I could know when it finishes, but it doesn't work.

As it's async jquery's ajaxStop triggers after every single ajax is done.

Not sure how to do this with promises either.

Help is appreciated.

EDIT: Here's how get_info looks like:

function get_info(url, page_num)
{
    $.ajax({ url: url, async: false, success: function(data) 
        { 
            // this is optional, sometimes it's true sometimes it's false
            if(views_enabled)
            {
                $.ajax({type:'POST', async:false, url:'/someurl/', data:{price: price}, success: function()
                {
                    item['views'] = data.views;
                    all_data.push(item);
                    console.log('finished item');
                }
                }); 
            }
            else
            {

                console.log('finished item');
            }
        } 
    });
}
madprops
  • 3,909
  • 5
  • 34
  • 42
  • I'm only seeing the first loop's ajax calls, was there another loop you left out? By the way, it sounds like you might be running into the classic async for loop problem - your code may refer to `i` when the loop has already long finished, and thus `i` is whatever it was at the loop termination. See http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – Caleb Jay Sep 01 '16 at 23:01
  • In that case you'd want to do `for(let i = 0...)` – Caleb Jay Sep 01 '16 at 23:02
  • You can see the second for loop inside the ajax callback. Also that's why I have the doSetTimeout function to avoid i being the wrong index number. – madprops Sep 01 '16 at 23:04
  • you can use Q.all (http://www.willvillanueva.com/introducing-q-all-in-promises/), which can get a list of promises and call then() when all promises are resolved. Keep in mind, that $.ajax is also a promise, so you can create array of promises first in a loop, and than use Q.all. The problem with all() is that If one of the given promises is rejected, the returned promise is immediately rejected, not waiting for the rest of the batch. If you want to wait for all of the promises to either be fulfilled or rejected, you can use Q.allSettled() (see https://github.com/kriskowal/q) – Andriy Sep 01 '16 at 23:30

0 Answers0