Несколько функций setTimeout () [duplicate]

Ну, причина в том, что привязки выполняются при выполнении кода, и выполняется определение функции, ну ... когда функции определены.

Сравните это:

class BananaBunch:
    bananas = []

    def addBanana(self, banana):
        self.bananas.append(banana)

Этот код страдает от такого же неожиданного случая. bananas - это атрибут класса, и, следовательно, когда вы добавляете к нему вещи, он добавляется ко всем экземплярам этого класса. Причина в том, что это точно то же самое.

Это просто «Как это работает», и заставить его работать по-другому в функциональном случае, вероятно, будет сложно, а в случае класса вероятно невозможно или, по крайней мере, замедлить объект создание экземпляра, так как вам придется хранить код класса и выполнять его при создании объектов.

Да, это неожиданно. Но как только пенни падает, она прекрасно вписывается в то, как работает Python в целом. На самом деле, это хорошее учебное пособие, и как только вы поймете, почему это происходит, вы будете намного лучше читать python.

Это говорит о том, что он должен занимать видное место в любом хорошем учебнике Python. Потому что, как вы говорите, все рано или поздно сталкиваются с этой проблемой.

1
задан Felix Kling 24 December 2011 в 14:13
поделиться

6 ответов

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

var i=0;

function sendEmailNow() {
     SendEmail(i);
     ++i;
   if(i<20) {
        setTimeout(sendEmailNow, 5000);
    }
}
2
ответ дан Pradeep 21 August 2018 в 02:43
поделиться
  • 1
    это работает, спасибо – Dan Dinu 24 December 2011 в 14:19
  • 2
    Избегайте глобальных переменных. Это можно сделать без. – PointedEars 24 December 2011 в 14:31
  • 3
    @PointedEars Да, это можно сделать. И я также соглашаюсь, что глобальные переменные являются злыми, но это касается проблем приложений JavaScript или веб-страниц с использованием большей части кода JS. Здесь я не передаю конструкцию функции (чтобы избежать глобальной переменной) только для того, чтобы сделать ее более читаемой (что также желательно). – Pradeep 24 December 2011 в 14:37
  • 4
    Это можно сделать без глобального i и без выражения функции, см. Другие ответы. Но выражения функций являются важным инструментом, о котором следует узнать. – PointedEars 24 December 2011 в 16:22

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

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

var email_count = 20;

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

setTimeout(sendMails, 5000)
1
ответ дан minikomi 21 August 2018 в 02:43
поделиться

Сначала передайте функцию 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
ответ дан pimvdb 21 August 2018 в 02:43
поделиться
  1. Избегайте jQuery. Изучите JavaScript.
  2. var i = 0; (иначе протекают во внешнюю область или ошибку времени выполнения)
  3. Дополнительная закрытие:
    window.setTimeout(
      (function (j) {
         return function () {
           sendEmail(j);
         };
       }(i)),
      i * 10000);
    
  4. sendEmail (стиль кода: не конструктор)
  5. Вы действительно хотите избежать $id в серверном коде, чтобы предотвратить SQL injection .
0
ответ дан PointedEars 21 August 2018 в 02:43
поделиться

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

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

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

2
ответ дан Svend 21 August 2018 в 02:43
поделиться

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

Рабочая демонстрация: 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
ответ дан Usman 21 August 2018 в 02:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: