0

I'm making a mailing list script that takes advantage of ajax (async=false) to send emails in chunks.

Basically the cycle is this:

var i = 0;
for(i;i<num_rows;i=i+mxt){
    if($("#panic").val()=='1'){
        break;
    }
    perc = (i*100)/num_rows;
    startThread(i,perc);
}

Tha panic value is set by a button, the problem is that during the cycle (that works) I can't interact with the page.

What am I doing wrong?

Thank you

EDIT:

function startThread(i,perc){
l_a = i;
l_b = mxt;

headers = '&mail_from='+mail_from+'&mail_from_name='+mail_from_name+'&mail_subject='+mail_subject;

$.ajax({  
    type: "POST", url: "ajax/thread.php", data: "l_a="+l_a+"&l_b="+l_b+headers, 
    success: function(html){ $("#progressbar").progressbar({value: perc}); },
    async: false
 });
}
4
  • 1
    Sounds pretty normal to me. How many rows are you processing that way? Commented Sep 3, 2010 at 8:53
  • More than 30k total, 100 rows per thread. The thing works like a charm, the only problem is that I would like a way to stop it before it finishes. Commented Sep 3, 2010 at 8:56
  • Can you provide the code for startThread? Commented Sep 3, 2010 at 9:00
  • Edited to include the startThread function. Commented Sep 3, 2010 at 9:03

1 Answer 1

4

Your startThread() function name is misleading, because JavaScript in web browsers in not only single threaded, but it shares the same thread with the page rendering.

Since you're using async=false, the $.ajax call become a blocking function, and this blocks the page rendering thread, making the UI unresponsive.

Quoting the jQuery documentation (emphasis added):

async

Default: true

By default, all requests are sent asynchronous (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active.

Possible solutions:

  • Piggyback your data in one JSON object, and send just one $.ajax request. If possible use async=true.
Sign up to request clarification or add additional context in comments.

7 Comments

No, you are wrong, try to comment out the startThread from the for cycle and you'll see that it's the for cycle not the ajax calls that blocks the UI!
I want to add something else. If you launch a for cycle with ajax calls (async) you are basically destroying the purpose of this. Each thread send chunks of email then pauses, If I launched 100+ concurrent ajax calls would be the same as sending them all to the smtp server.
@0plus1: Thanks for the downvote :) ... However, both are blocking. The $.ajax() with async=false blocks until the server returns a response. That's typically a few tens/hundreds of milliseconds... The for loop blocks depending on the number of iterations. Doing a while (true) { } blocks the UI... I'm not aware of the logic of your application. Mine was just an attempt to show you why you were having problems.
@0plus1: Updated my answer with a citation from the jQuery docs.
@0plus1: Is this solution for a public website, or is it going to be deployed in an internal/local environment? Because you could consider Web Workers to have multiple threads in JavaScript. Web Workers can do Ajax requests. The only problem is that they are not supported in some popular browsers (IE). That's why I asked if this is a public thing... If you can use Web Workers, you may want to check this related article: hacks.mozilla.org/2009/07/working-smarter-not-harder
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.