JavaScript спит с SetTimeout - PullRequest
       0

JavaScript спит с SetTimeout

1 голос
/ 24 декабря 2011

Я пытаюсь отправить электронное письмо с задержкой в ​​10 секунд. Я написал этот код:

$(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);
    });
}

серверный код (php) получает идентификатор и выбирает электронное письмо с указанным идентификатором из базы данных

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

затем отправляет электронное письмо и отправляет обратно текущее электронное письмо

echo email;

Однако что-то здесь не так. Похоже, что функция js ждет 5 секунд, а затем отображает все 20 адресов электронной почты одновременно.

Можете ли вы сказать мне, что я делаю неправильно? Любой обходной путь «сна» будет высоко оценен :)

Ответы [ 6 ]

3 голосов
/ 24 декабря 2011

Использовать интервал вместо цикла.

Рабочая демоверсия: http://jsfiddle.net/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)

 });
2 голосов
/ 24 декабря 2011

Сначала передайте функцию в setTimeout.

Во-вторых, вам будет лучше, если вы установите время ожидания для следующего в очереди после завершения текущего.

В цикле for:

sendEmail(0); // start sending first

и в обратном вызове:

      , function(data) {
          if(id < 19) { // if next should be sent
              setTimeout(function() {
                  SendEmail(id + 1);
              }, 5000);
          }
          var toAppend = "<span>     " + data + "</span>"
          $("#sentTo").append(toAppend);
      }
2 голосов
/ 24 декабря 2011

Вы должны создать функцию, которая вызывает себя через 5 секунд

var i=0;

function sendEmailNow() {
     SendEmail(i);
     ++i;
   if(i<20) {
        setTimeout(sendEmailNow, 5000);
    }
}
2 голосов
/ 24 декабря 2011

В результате вы вызываете setTimeout 20 раз, один за другим, с таймаутом в 5 секунд. Естественно, все письма отправляются одновременно. Вы можете изменить цикл так, чтобы он выглядел так:

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

Хотя есть много других вариантов, и они будут зависеть от того, что лучше всего подходит для вашей конкретной проблемы.

1 голос
/ 24 декабря 2011

Ваш цикл настраивает 20 таймеров для ожидания 5 секунд, а затем позволяет всем им работать сразу.

Попробуйте что-то вроде этого:

var email_count = 20;

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

setTimeout(sendMails, 5000)
0 голосов
/ 24 декабря 2011
  1. Избегайте jQuery.Изучите JavaScript.
  2. var i = 0; (в противном случае утечка во внешнюю область или ошибка времени выполнения)
  3. Дополнительное закрытие:

    window.setTimeout(
      (function (j) {
         return function () {
           sendEmail(j);
         };
       }(i)),
      i * 10000);
    
  4. sendEmail (стиль кода: не конструктор)
  5. Вы действительно хотите экранировать $id в коде на стороне сервера, чтобы предотвратить SQL-инъекцию .
...