es6 Generator

5721 단어

간단한 소개

  • 이를 하나의 상태기로 이해하고 여러 개의 내부 상태를 봉인한다. Generator 함수를 실행하면 하나의 범람기 대상을 되돌려주고Generator 함수 내부의 모든 상태를 순서대로 범람할 수 있다.
  • 정의할 때function과 함수명 사이에 별표가 있음
  • 내부에 yield(산출)문구를 사용하여 서로 다른 내부상태를 정의
  • 범람기 대상의next 방법을 호출하여 바늘을 다음 상태로 이동시킵니다
  • Generator 함수를 호출하면 이 함수는 실행되지 않고 내부 상태를 가리키는 바늘 대상을 되돌려줍니다.next 방법을 호출할 때마다 내부 바늘은 함수 머리나 지난번에 멈춘 곳에서 다음 yield 문장 (또는return 문장) 을 만날 때까지 실행됩니다.Generator 함수는 세그먼트로 실행되며, yield 문장은 실행을 정지하는 표시이며,next 방법은 실행을 복원할 수 있습니다
    function* helloWorldGenerator() {
      yield 'hello';
      yield 'world';
      return 'ending';
    }
    
    var hw = helloWorldGenerator();
    
    hw.next()
    // { value: 'hello', done: false }
    
    hw.next()
    // { value: 'world', done: false }
    
    hw.next()
    // { value: 'ending', done: true }, done true
    
    hw.next()
    // { value: undefined, done: true }
    

    yield 문

  • 범람기 대상의next가 yield 문장을 만나면 다음 동작을 일시 정지하고 yield 뒤에 있는 표현식의 값을 따라 되돌아오는 대상의value 속성 값
  • 으로 한다.
  • 다음에next 방법을 호출할 때 다음 yield 문장
  • 을 만날 때까지 계속 아래로 실행합니다
  • 새로운 yield 문장을 만나지 못하면 함수가 끝날 때까지 리턴 문장 뒤에 있는 표현식의 값을 리턴 문장 뒤에 있는value 속성 값으로 하고 없으면 undefined
  • 로 되돌려줍니다
  • yield 문장이 하나의 표현식에 사용되면 원괄호 안에 넣어야 하며 함수 매개 변수나 부수 표현식의 오른쪽을 제외
  • yield와return의 차이점은 매번 yield를 만나면 함수가 실행을 멈추고 다음에 이 위치에서 계속 뒤로 실행되며,return은 위치 기억 기능을 갖추지 못한다는 것이다.한 함수 안에서 한 번(또는 하나)return 문장만 실행할 수 있지만 여러 번(또는 여러 개)yield 문장을 실행할 수 있기 때문에Generator 함수는 일련의 값, 즉 생성기의 뜻을 되돌릴 수 있다.
    ield 문장 자체에 되돌아오는 값이 없거나, 항상 undefined로 되돌아옵니다.next 방법은 매개 변수를 가져올 수 있습니다. 이 매개 변수는 이전 yield 문장의 반환값으로 간주됩니다.첫 번째next 방법을 사용할 때 파라미터를 가지고 있을 수 없습니다. V8 엔진은 첫 번째next 방법을 사용할 때의 파라미터를 직접 무시합니다. 두 번째next 방법을 사용할 때부터만 파라미터가 유효합니다.의미에서 첫 번째next 방법은 플러그인 대상을 시작하는 데 사용되기 때문에 파라미터를 가지고 있지 않습니다.
    function* f() {
      for(var i=0; true; i++) {
        var reset = yield i;
        if(reset) { i = -1; }
      }
    }
    
    var g = f();
    
    g.next() // { value: 0, done: false }
    g.next() // { value: 1, done: false }
    g.next(true) // { value: 0, done: false }
    
    

    next 방법의 매개 변수를 통해Generator 함수 내부에 값을 입력합니다
    function* dataConsumer() {
      console.log('Started');
      console.log(`1. ${yield}`);
      console.log(`2. ${yield}`);
      return 'result';
    }
    
    let genObj = dataConsumer();
    genObj.next();
    // Started
    genObj.next('a')
    // 1. a
    genObj.next('b')
    // 2. b
    

    Iterator 인터페이스와의 관계

  • Generator 함수를 실행한 후 Iterator 객체로 돌아가기
  • for...of 주기, 확장 연산자(...),값 및 Array를 구문 해제합니다.from 방법 내부에서 호출된 것은 모두 범람기 인터페이스를 사용합니다. 즉,Generator 함수를 자동으로 범람할 수 있습니다
     (...) , 。
    
    let z = { a: 3, b: 4 };
    let n = { ...z };
    n // { a: 3, b: 4 }
    
     。
    
    let ab = { ...a, ...b };
    //  
    let ab = Object.assign({}, a, b);
    
    

    Generator.prototype.return()

  • 트랙터 대상의return 방법은 주어진 값을 되돌려주고 Generator 함수를 끝낼 수 있음
  • function* gen() {
      yield 1;
      yield 2;
      yield 3;
    }
    
    var g = gen();
    
    g.next()        // { value: 1, done: false }
    g.return("foo") // { value: "foo", done: true },return , vaule undefined
    g.next()        // { value: undefined, done: true }
    
    

    yield* 문

  • 한 Generator 함수에서 다른 Generator 함수를 실행하는 데 사용
  • function* foo() {
      yield 'a';
      yield 'b';
    }
    
    function* bar() {
      yield 'x';
      yield* foo();
      yield 'y';
    }
    
    //  
    function* bar() {
      yield 'x';
      yield 'a';
      yield 'b';
      yield 'y';
    }
    
    //  
    function* bar() {
      yield 'x';
      for (let v of foo()) {
        yield v;
      }
      yield 'y';
    }
    
    for (let v of bar()){
      console.log(v);
    }
    // "x"
    // "a"
    // "b"
    // "y"
    
    
    
    yield* Generator , for...of 만약에 yield* 뒤에 하나의 그룹이 따라가면 그룹의 원생이 플러그인을 지원하기 때문에 그룹 구성원, 그리고 문자열 같은 Iterator 인터페이스가 있는 데이터 구조를 플러그인으로 옮긴다.
    function* gen(){
      yield* ["a", "b", "c"];
    }
    
    gen().next() // { value:"a", done:false }
    
    
    //  ,
    //  、 
    function Tree(left, label, right) {
      this.left = left;
      this.label = label;
      this.right = right;
    }
    
    //  (inorder) 。
    //  , generator 。
    //  , yield* 
    function* inorder(t) {
      if (t) {
        yield* inorder(t.left);
       �����        yield t.label;
        yield* inorder(t.right);
      }
    }
    
    //  
    function make(array) {
      //  
      if (array.length == 1) return new Tree(null, array[0], null);
      return new Tree(make(array[0]), array[1], make(array[2]));
    }
    let tree = make([[['a'], 'b', ['c']], 'd', [['e'], 'f', ['g']]]);
    
    //  
    var result = [];
    for (let node of inorder(tree)) {
      result.push(node);
    }
    
    result
    // ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    
    

    Generator의 일부 응용 프로그램


    비동기식

    yield , next
    function* main() {
        var result = yield request("http://some.url");
        var resp = JSON.parse(result);
        console.log(resp.value);
    }
    function request(url) {
        makeAjaxCall(url, function(response) {
            it.next(response);   // yield , , response 
        });
    }
    var it = main();
    it.next();
    
    

    프로세스 제어

    ,
    function* parallelDownloads() {
      let [text1,text2] = yield [
        taskA(),
        taskB()
      ];
      console.log(text1, text2);
    }
    
    

    iterator 인터페이스 배치하기

    function* iterEntries(obj) {
      let keys = Object.keys(obj);
      for (let i=0; i < keys.length; i++) {
        let key = keys[i];
        yield [key, obj[key]];
      }
    }
    
    let myObj = { foo: 3, bar: 7 };
    
    for (let [key, value] of iterEntries(myObj)) {
      console.log(key, value);
    }
    
    // foo 3
    // bar 7
    
    

    좋은 웹페이지 즐겨찾기