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
)
}
}