JS(교체 프로토콜)에서 생성기 함수를 어떻게 실현합니까

JS에서 생성기 함수를 구축하는 방법과 yield 키워드를 사용하는 방법을 빠르게 파악합니다.
전체 텍스트 읽기 또는 Youtube에서 내 코드 보기

요컨대

  • '수동'구현iterableiterator 프로토콜에 비해 생성기 함수는 우리가 더욱 간소화된 프로토콜 구현을 작성할 수 있도록 한다.
  • 키워드function 뒤에 별표를 붙여서 생성기 함수를 정의합니다
  • 생성기 함수를 호출할 때마다 function* myGenerator() { ... } 대상을 되돌려주고 이 대상은 호출된 생성기 함수의 실례이다.따라서 생성기 함수의 코드는 실제로Generator 대상의 작업 방식을 정의했다.
  • , Generator 대상 실현Generatoriterable 협의가 이루어져 iterator와 순환하여 사용할 수 있다.이것은 for ... of ... 대상의 주요 용례이다.
  • 생성기 함수/대상 배후의 메커니즘은 어떤 상태 함수로 볼 수 있다.코드가 중단된 위치를 기억하고 다음 호출에서 계속 실행됩니다.
  • 키워드Generator가 가능합니다.그것으로 yield 키워드를 대체합니다.이것은 지정한 값을 호출자에게 되돌려주고 생성기 함수의 실행을 중단하며 계속해야 할 부분을 기억합니다.

  • 토대


    생성기 함수는 교체기 대상을 만드는 대체 방법으로 볼 수도 있고, 어떤 상태 함수로 볼 수도 있다.
    함수를 호출할 때마다 처음부터 끝까지 실행되며, 실행 중 return 문장을 만나면 주어진 값을 호출자에게 되돌려줍니다.만약 네가 같은 함수를 다시 호출한다면, 그것도 처음부터 끝까지 운행할 것이다.
    발전기의 기능이 약간 다르다.그것은 후속 통화에서 중단되고 계속될 수 있다.우리가 이렇게 할 수 있는 관건은 소위 return 문장이다.그것의 작업 원리는 yield 문장과 유사하기 때문에, 그것의 값은 호출자에게 되돌아갈 것이다.그러나 함수의 상태와 코드가 실행되는 위치도 기억한다.생성기 함수를 다시 호출하면 지난번에 실행된 return 문장 다음에 계속 실행된다는 뜻이다.
    따라서 다음 생성기 함수를 처음부터 끝까지 완전히 실행하려면 네 개의 호출이 필요하다.세 번째 호출은 세 개의 주어진 값을 검색하는 데 사용되고, 네 번째 호출은 교체기를 종료하는 데 사용된다. ((((next() function 의 정의 참조)
    function* myGenerator() {
        yield 1;
        yield 2;
        yield 3;
    }
    
    let generator = myGenerator();
    console.log(generator.next().value); // 1
    console.log(generator.next().value); // 2
    console.log(generator.next().value); // 3
    console.log(generator.next().value); // undefined
    

    굴복/교체 가능한 프로토콜과 교체기


    알림: 교체기 및/또는 for ... of .../iterable 프로토콜에 익숙하지 않은 경우 다음을 보는 것이 도움이 될 수 있습니다.
    JS는 iterableiterable 두 가지 협의를 제공했다.예를 들어 실현iterator 프로토콜의 대상(예를 들어 수조)은 iterable 순환에서 주어진 대상의 내용을 교체하는 데 사용할 수 있다.for ... of ...iterable 협의는 밀접하게 연결되어 있다. iterator 대상은 iterable를 제공해야 하기 때문이다. 방법은 iterator에 접근할 수 있는 속성에 따라 제로 매개 변수 함수를 공개하는 것이다.복잡하게 들리지만 단순히 코드 행에 배치됩니다.
    const iterator = someIterable[Symbol.iterator]();
    
    그러나 항상 교체기를 직접 사용하기를 원하는 것은 아니다. 예를 들어 Symbol.iterator 순환 은밀하게iterables를 처리하는 것이다.다음 예시에서 실행할 때 호출for ... of ..., 생성된 교체기는 실행someIterable[Symbol.iterator]() 순환에 사용됩니다.
    for (const value of someIterable) {
        console.log(value);
    }
    

    사용자 정의 더블 링크 목록의 생성기 함수


    See the full code at
    https://github.com/crayon-code/js-doublylinkedlist-generator
    The code given here is based on the previous episode mentioned in


    쌍사슬표는 일련의 노드인데 그 중에서 각 노드는 그 앞의 노드와 뒤의 노드를 모두 안다.따라서 내부에 각 노드마다 실제 값의 속성for ... of ...과 앞의 노드value와 뒤의 노드previous의 속성이 있다.
    쌍사슬표의 첫 번째 노드는next이고 마지막 노드는head이다.
    따라서 생성기 함수를 작성하여 쌍사슬표의 시작부터 끝까지 교체할 수 있도록 하려면 몇 줄의 코드만 필요합니다.
    class DoublyLinkedList {
      ...
    
      // function definitions in a class
      // do not require the function
      // keyword, so only the asterisk
      // is written in front of the 
      // function identifier
      *[Symbol.iterator]() {
    
        // start iterating at the head
        let current = this.head;
    
        // current is falsy as soon as 
        // the last item was passed 
        // (or the list is empty)
        // so the loop would terminate 
        // (or not even start)
        while (current) {
    
          // retrieve the reference 
          // to the next item as well as
          // the current value
          const { next, value } = current;
    
          // advance current to the
          // (potentially) next item
          current = next;
    
          // and (statefully) return the
          // current value to the caller
          yield value;
    
          // and right after the yield 
          // statement code execution
          // is continued, so the next
          // thing that happens is the
          // re-evaluation of the
          // loop condition
        }
      }
    }
    
    그때부터 사용은 매우 간단했다.
    const dll = new DoublyLinkedList();
    ...
    
    // Now this implicitly uses
    // the generator function behind
    // [Symbol.iterator]
    for (const item in dll) {
    
    }
    

    역변환


    또한 생성기 함수를 작성하는 것은 마지막 항목부터 첫 번째 항목까지 목록을 교체하기만 하면 매우 쉽다.
    class DoublyLinkedList {
      ...
    
      *reverse() {
        let current = this.tail;
        while (current) {
          const { value, prev } = current;
          current = prev;
          yield value;
        }
      }
    }
    
    ... 이 또한 사용하기 쉽습니다.
    const dll = new DoublyLinkedList();
    ...
    
    // Note the call to reverse()
    for (const item in dll.reverse()) {
    
    }
    

    좋은 웹페이지 즐겨찾기