Search code examples
javascriptloopsecmascript-6for-of-loop

How does Break work in for-of loop when stopping a Generator?


So there are some ways to stopping a Generator in for of loop, but how does break send a signal to the Generator(in comparison with return in for-of)?

please consider the code.

As an example, the preceding code just increases a value from 1 to 10 ,and do pause and resume in between.

function *Generator() {

    try {
        var nextValue;

        while (true) {
            if (nextValue === undefined) {
                nextValue = 1;
            }
            else {
                nextValue++;
            }

            yield nextValue;
        }
    }
    // cleanup clause
    finally {
        console.log( "finally has been reached." );
    }
}

it loops over it 10 times by using for of:

var it = Generator();// it gets Generator's iterator

for (var v of it) {
    console.log(v); 

    if (v > 9) {

           //it.return("stop");//this is another tool for stopping, but it doesn't stop immediately.

           break; 

           console.log("it won't run");//this line won't run
    }
} 

When it.return() is used by the way, the implementation's clear(it is the main Object and has got the control, but what about the break?);


Solution

  • how does break send a signal to the Generator?

    The loop will call the IteratorClose operation, which basically amounts to invoking the iterator's .return() method with no arguments if the iterator object has such a method - which generators do. This also happens when a throw or return statement in the loop body is evaluated.

    When it.return() is used by the way, the implementation is clear

    …but horrible. As you found out, it doesn't stop immediately. That's because a method call just advances the generator and gets you some result back from it, but is has nothing to do with your loop. The loop body will just continue to be executed until the loop condition is evaluated again, which then will check the iterator and notice that it's already done.