async/await 구현

5754 단어

generator 함수

  • Generator 함수는 전체적으로 하나의 상태기이다. 내부에 yield가 몇 개 있으면 몇 개의 상태가 있다. Generator 함수가 실행될 때 매번 코드가 실행되지 않은 바늘 대상(범람기 대상 Iterator)을 되돌려주고 Generator의 각종 상태를 범람할 수 있다(Iterator.next에서 바늘을 이동하면 Generator 함수를 단계별로 실행할 수 있다)
  • {value:xx,done:false|||true}, 이 상태의 반환값과 이 스트리밍 대상이 마지막까지 스트리밍되었는지 여부
  • Iterator 인터페이스


    typescript의 인터페이스 설명은 다음과 같습니다: 플러그인 인터페이스 (Iterable), 바늘 대상 (Iterator),next 방법 반환값
    interface Iterable {
      [Symbol.iterator]() : Iterator,
    }
    
    interface Iterator {
      next(value?: any) : IterationResult,
    }
    
    interface IterationResult {
      value: any,
      done: boolean,
    }
    
    
  • 일종의 데이터 구조는 Iterator 인터페이스를 배치하기만 하면 우리는 이런 데이터 구조를'누적할 수 있는'(iterable)이라고 부른다.
  • ES6는 기본 Iterator 인터페이스를 데이터 구조의 Symbol에 배치하도록 규정하고 있다.iterator 속성, 또는 하나의 데이터 구조는 Symbol만 있으면 된다.iterator 속성은'반복 가능'(iterable)
  • 으로 볼 수 있습니다.
    - ES6의 일부 데이터 구조는 원래 Iterator 인터페이스(예를 들어 수조)를 갖추고 있다. 즉, 어떠한 처리도 하지 않고 for...of 순환.이러한 데이터 구조에는 Symbol이 기본적으로 배치되어 있기 때문입니다.iterator 속성 (아래 참조), 다른 데이터 구조는 없습니다. (예: 대상)Symbol이 구축된 경우iterator 속성의 데이터 구조는 역력기 인터페이스를 배치한 것이라고 한다.이 인터페이스를 호출하면, 역력기 대상을 되돌려줍니다
    Iterator 인터페이스를 호출하는 경우
  • (1) 수조와 Set 구조를 해체할 때 Symbol을 기본적으로 호출합니다.iterator 방법.
  • (2) 확장 연산자 확장 연산자(...)기본 Iterator 인터페이스도 호출됩니다.
  • (3)yield*yield* 뒤에 있는 것은 범람 가능한 구조로 이 구조의 범람기 인터페이스를 호출한다.
  • let generator = function* () {
      yield 1;
      yield* [2,3,4];
      yield 5;
    };
    
    var iterator = generator();
    
    iterator.next() // { value: 1, done: false }
    iterator.next() // { value: 2, done: false }
    iterator.next() // { value: 3, done: false }
    iterator.next() // { value: 4, done: false }
    iterator.next() // { value: 5, done: false }
    iterator.next() // { value: undefined, done: true }
    
    

    for...인 순환에는 몇 가지 단점이 있다.
    그룹의 키 이름은 숫자입니다. 그러나 for...in 순환은 문자열을 키 이름 '0', '1', '2' 등으로 한다.for...인 순환은 디지털 키 이름뿐만 아니라 수동으로 추가된 다른 키도 반복할 수 있으며 원형 체인의 키도 포함한다.어떤 경우, for...in 순환은 키 이름을 임의의 순서로 반복합니다.어쨌든 for...인 순환은 주로 스트리밍 대상을 위해 설계된 것으로 스트리밍 그룹에 적용되지 않습니다.완일봉의 es6 문법을 여러 번 보고서야 Generator 함수가 하나의 트랙터로 되돌아오는 것을 알았다. 이 트랙터는 Generator 함수의 실행을 제어하기 위해 next () 방법을 제공한다. 일시 정지한다.일시 중지된 표현식 플래그
    Starter 버전의 Generator 함수 범퍼 자체 실행 함수:
    //   callback 
    var timeout = (time)=>{
      return (callbck)=>{
           setTimeout(()=>{
          console.log('time',time)
          callbck()
        },time)
      }
    }
    
    // Generator  
    function* callbackGenerator() {
      var res = yield timeout(2000) //   yield  value  callback    next callback 
      var res1 = yield timeout(2000)
    }
    
    // callback    
    function run (Generator) {
      var hw = Generator();
     const  next = ()=>{
       const aa = hw.next()
       if(!aa.done){
        aa.value(next) 
       }else{
         return true
       }
     }
     next()
    }
    
    run(callbackGenerator)
    
    
    //   promise  
    var timeout = (time)=>{
      return new Promise((resolve)=>{
           setTimeout(()=>{
          console.log('time',time)
          resolve(time+2000)
        },time)
      })
    }
    
    // Generator  
    function* callbackGenerator() {
      var res = yield timeout(2000) //   yield  value promise  next then 
      var res1 = yield timeout(res)
    }
    
    // promise   
    function run (Generator) {
      var hw = Generator();
     const  next = (query)=>{
       var aa = hw.next(query)
       if(!aa.done){
        aa.value.then(next) 
       }else{
         return true
       }
     }
     next()
    }
    
    run(callbackGenerator)
    
    

    핵심 사상:generator 플러그인 생성기 함수의 세그먼트 집행을 이용하여 플러그인 대상이next 방법을 집행한 후에만 제어권을 주고 완성 후callback||promise.then () 에서 다음next를 호출할 때 제어권을 계속 복구하는 기능으로 이루어졌습니다


    Async await에서 이 점을 본격적으로 활용했습니다.

  • yield 표현식 제어권 넘기기
  • 두 가지 방법으로 이 점을 해낼 수 있다.(1) 콜백 함수.비동기 동작을 Thunk 함수로 포장하여 리셋 함수에서 집행권을 반환합니다.
    (2) Promise 객체비동기 동작을 Promise 대상으로 포장하고 then 방법으로 집행권을 반환합니다.from http://es6.ruanyifeng.com/#docs/generator-async
  • generator 범람기 함수를 자동으로 실행
  • es7 async await 비동기 쓰기
    function sleep(ms) {
      return new Promise((resolve, reject) => {
        setTimeout(resolve, ms);
      });
    }
    
    async function test() {
      for (let i = 0; i < 10; i++) {
        await sleep(100);
      }
    }
    
    

    에스6로 전환하면 아래쪽입니다. 이렇게 async await는 실제로generator+yield 제어 프로세스+promise에서 리셋을 실현합니다.
    //_asyncToGenerator 이름 그대로 async to Generator 변환
  • await를 yield
  • 로 변환
  • ASync를 Generator
  • 로 변환
  • test를 호출하기 전asyncToGenerator 함수가 실행되었고 fn(Generator)이 익명의 실행 함수
  • 에 전달되었습니다.
  • 실제로 테스트를 호출하기 전에 테스트 방법은 Generator 플러그인 생성 함수 자체 실행을 실현하는 방법이 되었다
  • 테스트 귀속 실행 step 호출
  • next를 호출하여 실행기
  • 매번 실행할 때마다promise
  • 를 되돌려줍니다
  • promise의then방법에서next방법을 실행)
  • Generator 트래커를 자동으로 실행하여 비동기식
  • function _asyncToGenerator(fn) {
      return function () {
        var gen = fn.apply(this, arguments);
        return new Promise(function (resolve, reject) {
          function step(key, arg) {
            try {
              var info = gen[key](arg);
              var value = info.value;
            } catch (error) {
              reject(error);
              return;
            }
            if (info.done) {
              resolve(value);
            } else {
              return Promise.resolve(value).then(function (value) {
                return step("next", value);
              },
                function (err) {
                  return step("throw", err);
                });
            }
          }
          return step("next");
        });
      };
    }
    
    function sleep(ms) {
      return new Promise((resolve, reject) => {
        setTimeout(resolve, ms);
      });
    }
    
    let test = function () {
      var ref = _asyncToGenerator(function* () {
        for (let i = 0; i < 10; i++) {
          yield sleep(100);
        }
      });
    
      return function test() {
        return ref.apply(this, arguments);
      };
    }();
    

    참조:https://www.jianshu.com/p/862ab6d1a2f6

    좋은 웹페이지 즐겨찾기