Zg Ma
Zg Ma

Reputation: 37

Confused about javascript generator function

Why the value of the final b is not 24 but 18?
I think when function s2 is called the last time, a is 12 and last is 2, so b should be equal to 12 * 2 = 24.

let a = 1, b = 2;

function* foo() {
  a++;
  yield;
  b = b * a;
  a = (yield b) + 3;
}

function* bar() {
  b--;
  yield;
  a = (yield 8) + b;
  b = a * (yield 2);
}

function step(gen) {
  let it = gen();
  let last;

  return function () {
    last = it.next(last).value;
  };
}

let s1 = step(foo);
let s2 = step(bar);

s2(); //b=1 last=undefined

s2(); //last=8

s1(); //a=2 last=undefined

s2(); //a=9 last=2

s1(); //b=9 last=9

s1(); //a=12

s2(); //b=24

console.log(a, b);

Upvotes: 1

Views: 73

Answers (1)

Moishe Lipsker
Moishe Lipsker

Reputation: 3034

In the last line of the bar function:

b = a * (yield 2);

the code already ran the a * before running (yield 2). So it would seem that a is already evaluated at that point.

If you move the multiplication by a to after (yield 2), then it seems a is evaluated after (yield 2) is run, thereby ensuring you get the most up to date value of a.

So the last line of the bar function could become:

b = (yield 2) * a;

This can be seen in the example below.

let a = 1, b = 2;

function* foo() {
  a++;
  yield;
  b = b * a;
  a = (yield b) + 3;
}

function* bar() {
  b--;
  yield;
  a = (yield 8) + b;
  b = (yield 2) * a;
}

function step(gen) {
  let it = gen();
  let last;

  return function () {
    last = it.next(last).value;
  };
}

let s1 = step(foo);
let s2 = step(bar);

s2(); //b=1 last=undefined

s2(); //last=8

s1(); //a=2 last=undefined

s2(); //a=9 last=2

s1(); //b=9 last=9

s1(); //a=12

s2(); //b=24

console.log(a, b);

Upvotes: 1

Related Questions