Javascript сон с SetTimeout

Я пытаюсь отправить электронную почту с задержкой в ​​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 адресов электронной почты одновременно.

Можете ли вы сказать мне, что я делаю неправильно? любое "обходное" обращение будет с благодарностью:)

Ответ 1

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

var i=0;

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

Ответ 2

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

Рабочая демонстрация: 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)

 });

Ответ 3

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

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

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

Ответ 4

Сначала передайте функцию 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);
      }

Ответ 5

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

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

var email_count = 20;

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

setTimeout(sendMails, 5000)

Ответ 6

  • Избегайте jQuery. Изучите JavaScript.
  • var i = 0; (иначе утечка в внешнюю область или ошибку времени выполнения)
  • Дополнительное закрытие:

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