Home > OS >  javascript delay in a for loop
javascript delay in a for loop

Time:01-25

I can't seem to figure out how to add a delay in a javascript for loop. I am looping over emails, for each emails I am sending it to the backend that will actually send the email newsletter. In order not to send too fast, I want to introduce a pause in the for loop. From console.log it can verify that the delay method is called AFTER execution of the entire for loop. I have Googled around this topic, but I am not sure I understand the proposed solutions some related to using the let and others related to blocking. I am new to javascript, and therefore not fully sure that I understand WHY delay is called at the end of the for loop.

async sendNewsletter (event) {
       
        //Loop over each email and gather the html content followed by sending it to backend
        let counter = 0
        for (const option of this.includedEmailList.options) {
          

            //Call the backend 
            const response = await fetch('url',
            {
                method:'POST',
                credentials:'same-origin',
                headers:{
                    'Content-Type': 'application/json',
                    'Accept' : 'application/json',
                },
                redirect: 'follow',
                body: JSON.stringify({
                    'emailSubject' : this.emailSubject.value,
                    'email' : option.value,
                    'plainTextEmail' : this.emailPlainText.value,
                    'htmlEmail' : this.hiddenHTML.innerHTML}),
            });  

            const responseJson = await response.json();
            console.log(responseJson['status']);
            this.emailSentStatus.innerHTML = responseJson['status'];

            //I need to delay the loop
            counter  ;
            this.delay(10000 * counter);
        }
        //Everything has been sent. Leave a message and disable the submission button to prevent 

        emailSentStatus.innerHTML = `all emails have been sent!`;
    }

delay (timeMilliseconds) {
        //To be used in for loop to delay the loop and to slow down
        setTimeout(() => {
            console.log('in delay');
            console.log(timeMilliseconds);}, timeMilliseconds);
    }

CodePudding user response:

delay (timeMilliseconds) {
return new Promise (r => 
        //To be used in for loop to delay the loop and to slow down
        setTimeout(() => {
            r()
            console.log('in delay');
            console.log(timeMilliseconds);}, timeMilliseconds);
})
    }
await this.delay(10000);

CodePudding user response:

I understand it much better now thanks to Pointy's comment pointing out that it is a scheduler. My understanding initially was trying to delay the for loop, in stead of creating many tasks with the setTimeout method each with an increasing delay. The code snippet below work as expected.

async submitNewsletterToBackend(emailSubject, emailTo, plainText, htmlMessage) {
        //Call the backend 
        const response = await fetch('url',
        {
            method:'POST',
            credentials:'same-origin',
            headers:{
                'Content-Type': 'application/json',
                'Accept' : 'application/json',
            },
            redirect: 'follow',
            body: JSON.stringify({
                'emailSubject' : emailSubject,
                'email' : emailTo,
                'plainTextEmail' : plainText,
                'htmlEmail' : htmlMessage}),
        });  

        const responseJson = await response.json();
        console.log(responseJson['status']);
        this.emailSentStatus.innerHTML = responseJson['status'];
    }

    sendNewsletter (event) {
        if (this.includedEmailList.options.length === 0) {
            return
        }

        let counter = 0
        for (const option of this.includedEmailList.options) {
            
            counter  ;
            setTimeout(this.submitNewsletterToBackend, counter * 100, 
                this.emailSubject.value,
                option.value,
                this.emailPlainText.value,
                this.hiddenHTML.innerHTML
                )
        }
    }
  • Related