Iterating Through Tasks Made Easy
Problem
You want to iterate over a set of tasks, but not all at the same time, and not all within
the same expression
Solution
Use an iterator, a new ES 6 protocol:
function makeIterator(array){ var nextIndex = 0; return { next: function(){ return nextIndex < array.length ? {value: array[nextIndex++], done: false} : {done: true}; } } } var tasks = [{"task": function() { console.log('hello from a'); }}, {"task": function() { console.log('hello from b'); }}]; var taskRunner = makeIterator(tasks); taskRunner.next().value.task(); taskRunner.next().value.task(); It has the following results: hello from a hello from b
EXPLAIN
The ES 6 iterator isn’t a new object or construct, but an implementation strategy, or protocol. It’s not a new syntax, like spread, or a new built-in, like Map. As long as an existing object can support some specific characteristics, it can be used as an iterator. In the solution, a function is called, and returns an iterator over an array of functions.
The makeIterator() function accepts an array as argument and returns an object with one property: next(). This property is used to iterate over the array contents, but iteration doesn’t require a loop, and we don’t have to maintain the state of each array access via incremented index variable. Each successive next() returns the next value in the array.
Because each array value is a function, it can then be invoked. As an example, consider an online help system that walks the user through steps. As they complete each step, they hit the Enter key, and your code calls up the next data/ function using next().
The application isn’t blocking, as it would in a loop, and you don’t have to maintain an array counter as a global variable. When the list is complete, the done variable is set to true. So to make the implementation safer, you could use the following:
var taskRunner = makeIterator(tasks); var task = taskRunner.next(); console.log(task); if (!task.done) task.value.task(); task = taskRunner.next(); console.log(task); if (!task.done) task.value.task(); task = taskRunner.next(); console.log(task); if(!task.done) task.value;
{ value: { task: [Function] }, done: false } hello from a { value: { task: [Function] }, done: false } hello from b { done: true }
No comments:
Post a Comment