3

I have generator

function* pendingPage() {
    let value = 1;
    while (true)
        yield getPage(value++);
}

I have getPage() function

async function getPage(value) {
    const page = await service.getValidations(value);
    (page.data.customers.length === 0) ? service.isCustomersFinished = false : console.log(page.data.customers);
}

I have while infinite loop with the following syntax:

let generator = pendingPage()
while(true){
   generator.next();
}

And I want to use generator.next() function inside it. But the generator does not work.

I tried with the for loop, and it works fine.

So, what is the problem with it and how to use generator.next() inside infinite while loop?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Remzes
  • 269
  • 1
  • 3
  • 17
  • What is `generator`? – Bergi Aug 28 '17 at 21:48
  • How do you expect to ever break from the infinite loop? Of course infinite loops don't work, regardless what methods they call. – Bergi Aug 28 '17 at 21:49
  • What is your [actual problem](https://meta.stackexchange.com/q/66377)? Why are you using generators and infinite loops? – Bergi Aug 28 '17 at 21:50
  • 2
    A generator function's `yield` won't automatically wait for your async function to resolve. Don't confuse laziness with asynchronicity. – Redu Aug 28 '17 at 21:57
  • @Redu what do you mean – Remzes Aug 28 '17 at 21:58
  • @Redu why generator.next() works in for loop, but not in the while loop? – Remzes Aug 28 '17 at 22:00
  • 2
    Okay, now back to Bergi’s question: what are you actually trying to accomplish with this? Getting each page in sequence? – Ry- Aug 28 '17 at 22:01
  • @Ryan I have infinite amount of pages, which I can access with ?page=n query atthe end of URL, where n - number of the page. These pages contains json files. I want to retrieve info and put it to console.log. I want to do it async with generator, async/await and infinite while loop. When I do the same thing with for loop, it works fine, but not with while(true) loop – Remzes Aug 28 '17 at 22:04
  • @Remzes You mean that when you do it with a for loop, it does something but will not access all pages? – Bergi Aug 28 '17 at 22:12
  • 2
    @Remzes Why do you think you need a generator for this? An asynchronous infinite loop will suffice. – Bergi Aug 28 '17 at 22:13
  • @Remzes Do you want to send all the request accessing the pages in parallel, or sequentially? Are those really infinitely many pages, won't there be an end (like empty responses or 404 errors from the server)? – Bergi Aug 28 '17 at 22:14
  • @Bergi if it has no info, it contains empty object, so 404 error won't be occurred.I just wanna know how to use generator inside infinite while loop – Remzes Aug 28 '17 at 22:21
  • @Remzes So you really want it to end only when the program is killed? – Bergi Aug 28 '17 at 22:33
  • @Bergi For now - yes. I just wanna check will it work – Remzes Aug 28 '17 at 22:34
  • Then just use `await` in a loop. No generators. – Ry- Aug 28 '17 at 22:35
  • @Ryan So, delete generator and do normal loop? – Remzes Aug 28 '17 at 22:39
  • @Remzes: Yes. `while (true) await getPage(value++);` in `async function pendingPage()`. – Ry- Aug 28 '17 at 22:41

1 Answers1

2

And I want to use generator.next() function inside it.

There's absolutely no reason to use a generator here. The plain code

{
    let value = 1;
    while (true) {
        getPage(value++);
    }
}

does exactly the same as calling the pendingPage generator and iterating it forever.

So, what is the problem with it?

It's an infinite loop. That's the problem. It will call getPage forever, and block the whole process from doing anything else. That's kinda what you want if everything here was synchronous, but notice that getPage and specfically service.getValidations are asynchronous. Blocking everything includes preventing asynchronous callbacks from happening, which is the reason why you don't get any of the logs. With a bounded for loop, the iteration ended at some point and the callbacks had a chance to get called.

I want to retrieve info and put it to console.log. I want to do it async with generator, async/await and infinite while loop.

Omit the generator - it's not asynchronous anyway. You can do it only with async/await and an infinite loop:

(async function() {
    let value = 1;
    while (true) {
        await getPage(value++);
    }
}());

That's still an infinite loop, but it's suspended at every await to allow other things to happen.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thank you very much for the explanations! – Remzes Aug 28 '17 at 23:21
  • Could you give me please an explanation of the last function, or the source, where I can read about it – Remzes Aug 28 '17 at 23:31
  • @Remzes It's just an [IIFE](https://stackoverflow.com/questions/592396/what-is-the-purpose-of-a-self-executing-function-in-javascript) made `async`, allowing us to use `await` syntax inside its body. See [ES8 Immediately invoked async function expression](https://stackoverflow.com/q/40745153/1048572) for example. – Bergi Aug 28 '17 at 23:46