0

I currently have the following loop

for (const pk of likerpk)
{
     await likeMediaId(ig, pk.trim());

}

the issue is that i wanted to call likeMediaId every X seconds and after the whole likeMediaId is done I wanted to call the function called Y

I have tried putting a sleep inside a for loop but that does not help, it seems that it is still executing likeMediaId in parallel, while i always want to execute 1 likeMediaId at a time

basically the flow that i wanted is (assuming 3 items in the array)

likeMediaId()
sleep 60 seconds
likeMediaId()
sleep 60 seconds
likeMediaId()
sleep 60 seconds

call function Y

what is the most elegant way in doing this?

adit
  • 32,574
  • 72
  • 229
  • 373
  • you could use https://stackoverflow.com/questions/22707475/how-to-make-a-promise-from-settimeout in combination with what you alredy have, and control both with a Promise.all https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all – malarres Feb 27 '20 at 16:04
  • const { promisify } = require('util'); const sleep = promisify(setTimeout); /* later in the loop: */ await sleep(60000); – Martin Ždila Feb 27 '20 at 16:04
  • Most elegant way is code it not in a for loop. – epascarello Feb 27 '20 at 16:08

3 Answers3

0

if you're open to rxjs:

const likeMediaId$ = (pk) => from(likeMediaId(ig, pk.trim())); // observable from promise
from(likerpk).pipe( // observable stream from list items
  concatMap(item => of(item).pipe(delay(60000))) // wait 60 seconds
  switchMap(pk => likeMediatId$(pk)), // run the function
  finally(() => Y()) // at end, do this
).subscribe(
  result => console.log(result),
  error => console.log(error)
)

wana go super vanilla? why not try an interval?

let i = likerpk.length // counter
const clearInterval = setInterval(() => {
  i -= 1 // iterate
  await likeMediaId(likerPk[i]) // await (runs backwards)
  if (!i) { // out of items
    clearInterval() // clear
    Y() // run Y
  }
}, 60000) // every 60 seconds
bryan60
  • 28,215
  • 4
  • 48
  • 65
0

you can do it with a little helper:

// a little utility
const delay = (delay) => new Promise(resolve => setTimeout(resolve, delay));

for (const pk of likerpk)
{
     await likeMediaId(ig, pk.trim());
     await delay(60000);
}

Y();

it seems that it is still executing likeMediaId in parallel

Then this is an error in your function likeMediaId. It seems to resolve before the work is done. That's the only way all iterations could run basically in paralell.

Thomas
  • 11,958
  • 1
  • 14
  • 23
-1

you could use a timeout to do it. Maybe it's not the most elegant, but should work fine.

var i=0;

async function cycle() {
    await likeMediaId(ig, likerpk[i].trim());
    i++;
    if (i < likerpk.length) {
        setTimeout(cycle, 1000);
    }
}

cycle();
Drago96
  • 1,265
  • 10
  • 19