leo
leo

Reputation: 1185

How to understand javascript Generator?

I have a snippet of code

function* dataConsumer() {
   console.log('Started');
   console.log(`1. ${yield}`);
   console.log(`2. ${yield}`);
   return 'result';
}

let genObj = dataConsumer();
genObj.next();

and the running result is

Started

I don't understand why the second console.log can't output anything. Thanks for help.

Upvotes: 1

Views: 61

Answers (1)

Suren Srapyan
Suren Srapyan

Reputation: 68635

Generators are build on the top of Iterators. To understand generator, you need first to understand iterator. See the Documentation.

For a one flow it runs to the nearer yield and terminates the function call. After it when you call again next it will continue from where it was terminated and works again until the nearest yield and when there are no yields or it reaches to the return statement, it just finishes its call.

function* dataConsumer() {
  console.log('Started');
  console.log(`1. ${yield}`); // First `next` terminates before yield. Second `next` passes the value and terminates before the next yield.
  console.log(`2. ${yield}`); // Third call continues from the `yield` part and finishes the function, because we have returned
  return 'result';
}

let genObj = dataConsumer();
genObj.next();
genObj.next('yield1'); 
genObj.next('yield2'); 

You also can pass parameters to the next function, which will be put in the yield statement. Also the next function returns an object about the generator state with properties value and done. If function call is not finished, it returns done as false and at the end you can see that this is set to true.

function* dataConsumer() {
  console.log('Started');
  const x = yield; 
  console.log(`1. ${x}`);
  console.log(`2. ${yield}`); 
  return 'result';
}

let genObj = dataConsumer();
let result = genObj.next();
console.log(result);

result = genObj.next('x is yield1'); 
console.log(result);

result = genObj.next('yield2'); 
console.log(result);

genObj.next(); // This one has nothing to do

As you can pass parameters to the generator each step, you also can return a value from . You need to write something similar to return something, just replacing return with yield.

function* dataConsumer() {
  yield 1;
  yield 2;
  yield 3;
}

let genObj = dataConsumer();
let result = genObj.next();
console.log(result);

result = genObj.next(); 
console.log(result);

result = genObj.next(); 
console.log(result);

result = genObj.next(); 
console.log(result);

Upvotes: 3

Related Questions