Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper usage with ES6 generators and pagination

I've been thinking about this a bit, and I can't seem to come up with a reasonable solution about how to accomplish this. The problem statement is simple - write a generator that will lazily paginate a remote data set. To simplify things, this is ideally what I'd like for the user of my library to see:

for (var user of users()) { 
  console.log(user); 
}

I can't quite seem to get a generator working. I was thinking logic like this would work, but I can't figure out how to implement it.

function* users() {
  while (canPaginate) {
    yield* getNextPageOfUsers() // This will need to return an array of users from an http request
  }
}

I'm sure that I'm thinking about something wrong here, but I can't seem to find any examples of someone using a generator like this (mostly people using them with static data or people doing something like async(function*(){...}) which isn't exactly what I'm looking to do). The important part here is that I want the end user to be able to consume the data as described above.

-Vince

like image 988
vincentjames501 Avatar asked Jan 09 '15 17:01

vincentjames501


1 Answers

Generators are functions that, in effect, pause and yield back to their callers. But when called, they must synchronously either yield back a value or complete. So they can't return the result of an asynchronous operation for the same reason that normal functions can't return the result of an asynchronous operation.

As Benjamin pointed out, there's an ES7 proposal for asynchronous generators that would let them do that, but that's ES7, and so that's markedly in the future at this point. The consumption syntax is also affected (understandably; it's important for the people writing the call to know when something is going async, we can't have normal functions look synchronous when they aren't).

According to the current proposal, your code using async generators would look something like:

for (var user on users()) { 
  console.log(user); 
}

(Note the on instead of in or of.) But that may well change.

like image 178
3 revs, 2 users 54% Avatar answered Oct 25 '22 12:10

3 revs, 2 users 54%