admin管理员组

文章数量:1291676

I'm trying to send emails with a 10 seconds delay between. I wrote this code:

$(document).ready(function() {
    for (i = 0; i < 20; i++) {
        setTimeout("SendEmail(" + i + ")", 5000);
    }
});

function SendEmail(id) {
    $.get("mimesender.php?id=" + id, function(data) {
        var toAppend = "<span>     " + data + "</span>"
        $("#sentTo").append(toAppend);
    });
}

server side code(php) gets the id and selects the email with the specified id from the database

$query="select email from clienti where id =".$id;

then sends the email, and sends back the current email

echo email;

However, something is wrong here. It seems like the the js function waits for 5 seconds, and then displays all the 20 email addresses at once.

Can you tell me what I'm doing wrong ? any "sleep "workaround will be greatly appreciated :)

I'm trying to send emails with a 10 seconds delay between. I wrote this code:

$(document).ready(function() {
    for (i = 0; i < 20; i++) {
        setTimeout("SendEmail(" + i + ")", 5000);
    }
});

function SendEmail(id) {
    $.get("mimesender.php?id=" + id, function(data) {
        var toAppend = "<span>     " + data + "</span>"
        $("#sentTo").append(toAppend);
    });
}

server side code(php) gets the id and selects the email with the specified id from the database

$query="select email from clienti where id =".$id;

then sends the email, and sends back the current email

echo email;

However, something is wrong here. It seems like the the js function waits for 5 seconds, and then displays all the 20 email addresses at once.

Can you tell me what I'm doing wrong ? any "sleep "workaround will be greatly appreciated :)

Share Improve this question edited Dec 24, 2011 at 12:13 Felix Kling 817k181 gold badges1.1k silver badges1.2k bronze badges asked Dec 24, 2011 at 12:07 Dan DinuDan Dinu 33.4k25 gold badges83 silver badges119 bronze badges 2
  • 1 simply because your for loop doesn't wait the 5 seconds. – mas-designs Commented Dec 24, 2011 at 12:10
  • All the setTimeouts are basically called at the same time. – Felix Kling Commented Dec 24, 2011 at 12:12
Add a ment  | 

6 Answers 6

Reset to default 3

Use interval instead of loop.

Working demo: http://jsfiddle/xfVa9/2/

$(document).ready(function() {
    var tmr;
    var i=0;
    tmr=setInterval(function(){
        if(i<20){
            SendEmail(i);
            alert("Sent "+i)
            i++;
        }else{
            clearInterval(tmr);
        }

    },5000)

 });

You should create a function which calls itself after 5 seconds

var i=0;

function sendEmailNow() {
     SendEmail(i);
     ++i;
   if(i<20) {
        setTimeout(sendEmailNow, 5000);
    }
}

What happens is that you call setTimeout 20 times, just after one another, with a timeout of 5 seconds. So naturally, all emails gets sent at once. You could change the loop to look like this:

for (i=0;i<20;i++) {
    setTimeout("SendEmail("+ i + ")",(i+1)*5000);
}

There's alot of other options though, and they'd depend on just what suits your specific problem best.

First, pass a function to setTimeout.

Secondly, you'd be better off if you set the timeout for the next one in the queue after the current one is finished.

In the for loop:

sendEmail(0); // start sending first

and in the callback:

      , function(data) {
          if(id < 19) { // if next should be sent
              setTimeout(function() {
                  SendEmail(id + 1);
              }, 5000);
          }
          var toAppend = "<span>     " + data + "</span>"
          $("#sentTo").append(toAppend);
      }

Your loop is setting up 20 timers to wait 5 seconds, then letting them all go at once.

Try something like this:

var email_count = 20;

var sendMails = function(){
    SendEmail(email_count--);
    if(email_count > 0){
        setTimeout(sendMails, 5000);
    }
}

setTimeout(sendMails, 5000)
  1. Avoid jQuery. Learn JavaScript.
  2. var i = 0; (otherwise leak into outer scope or runtime error)
  3. Extra closure:

    window.setTimeout(
      (function (j) {
         return function () {
           sendEmail(j);
         };
       }(i)),
      i * 10000);
    
  4. sendEmail (code style: not a constructor)
  5. You really want to escape $id in the server-side code to prevent SQL injection.

本文标签: jqueryjavascript sleep with SetTimeoutStack Overflow