简体   繁体   中英

How to make this loop wait some time before showing next result when trying to loop a construct function?

I'm currently learning construct function in javascript and wanted to play some experiment about it, but ended stuck in here for like 5 hours and didn't what to do.

So, I have this (superclass) constructor function to made basic function of messaging and saving data about who is the sender. Why I made this superclass? Because there will be more than 1 subclasses that need same function (send message) and later i will add some different feature in every subclasses, but i will not put all my code here because that's working perfectly.


    const receiverLists = ['Ahmad', 'John', 'David'];

    class SenderProfile{
        // property
        constructor(sender){
            this.sender = String(sender);
        }

        // method
        sendMessage(message, receiver){
            console.log(`${this.sender} sent \`${message}\` to ${receiver} `);
        }
    }

    /* Let's try
       const emailUser = new SenderProfile('adam@test.com');
       emailUser.sendMessage('hi', 'john@test.com');
       
       output: adam@test.com sent hi to john@test.com
    */
 

And this is my subclass called TelegramSender. My expectations of this code is return all the result every 1 sec.

    class TelegramSender extends SenderProfile {
        constructor(sender){
            super(sender);
        }

        // add delay feature
        delayMessage(message){
            for(let i=0; i<=receiverLists.length; i++){
                setTimeout(() => {
                    console.log(`${this.sender} on Telegram was send \'${message}\' to ${receiverLists[i]}`);
                }, 1000)
            }
        }            
    }

The result is near my expectations because the result delayed 1 second before show up, but they still shows at the same time, i don't want that, i want every result will shows up after waiting 1 sec.

like this

  1. first result shows up after 1 sec -- wait 1 sec before second result shows up
  2. second result shows up. and so on...

please help me because i runs out energy to solve this.

I think you are looking for this:

class TelegramSender extends SenderProfile {
        ...
        delayMessage(message){
            for(let i=0; i<=receiverLists.length; i++){
                setTimeout(() => {
                   ...
                }, (i + 1) * 1000) // <--------------- increase the timeout
            }
        }            
    }

Basically what happens is the following: Your for-loop runs through in no time at all. While it does that, it stacks up all your setTimeouts "at the same time". Then they wait for the defined 1000ms, and execute. It looks like they dont wait, because they are almost created at the same time.

What you have to do is define a "waiting" variable, and increase the timer on 1000ms each time your for-cycle is finished. Like so:

delayMessage(message){
        for(let i=0; i<=receiverLists.length; i++){
          const waitTime = (i + 1) * 1000;
            setTimeout(() => {
                console.log(`${this.sender} on Telegram was send \'${message}\' to ${receiverLists[i]}`);
            }, waitTime)
        }
    }    

What now happens is the following: Your for-loop runs through super fast, and it defines the waitTime as follows:

Cycle 1: i=0 -> waitTime = 0 + 1 * 1000 -> 1000ms
Cycle 2: i=1 -> waitTime = 1 + 1 * 1000 -> 2000ms
Cycle 3: i=2 -> waitTime = 2 + 1 * 1000 -> 3000ms
...

That should be your desired behavior.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM