Search code examples
javascriptgenerator

Javascript generator doesn't yield new results


I'm creating a generator function in React, to produce an insertionSort animation, step-by-step:

function* insertionSort(data) { // yield state of array at each step of sorting
  const inputArr = [...data]
  let n = inputArr.length
  for (let i = 1; i < n; i++) {
    // Choosing the first element in our unsorted subarray
    let current = inputArr[i]
    // The last element of our sorted subarray
    let j = i - 1
    while (j > -1 && current < inputArr[j]) {
      inputArr[j + 1] = inputArr[j]
      j--
    }
    inputArr[j + 1] = current
    yield inputArr
  }
  yield inputArr
}

export default insertionSort

and calling the next() function on every button press:

      <button
        onClick={() => {
          console.log(insertionSort(data).next().value)
        }}>
        Insertion Sort
      </button>

However, only the first button press produces the expected results. Every subsequent press just reproduces the same thing.

I am confident the function logic is correct, as removing the generator syntax and just using it as a normal loop produces the correct results.

Am I missing something in how yield works?


Solution

  • Every call to insertionSort(data) creates a new generator that starts from the beginning. You're repeatedly doing the first step on a new instance. You'll want to use

    const sorter = useRef();
    
    <button onClick={() => {
      console.log(data);
      sorter.current = insertSort(data);
    }}>
      Start Insertion Sort
    </button>
    <button onClick={() => {
      console.log(sorter.current.next().value);
    }}>
      Step
    </button>