프런트엔드 비동기 솔루션 - 4.2(generator+promise)

왜generator와promise의 결합을 실현해야 합니까?대부분의 인터넷의 글은 모두 잘못을 더욱 간단하게 처리하기 위해서라고 말하지만, 이것은 내가 잠시 깨닫지 못했기 때문에 나는 오히려 사실 차이가 많지 않다고 생각한다.그래도 먼저 용법을 배워보자.먼저 간단한 용법부터 말하자면
// 
function request() {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      let num = Math.random();
      if (num > 0.9) {
        reject(num + "request err")
      } else {
        resolve(num * 100);
      }
    }, 100)
  })
}

let it = gen();
let p = it.next().value;//  yield Promise   p
p.then(res => it.next(res).value, err => it.throw(err));//  , (gen) 

function* gen() {
  try {
    let response = yield request();
    console.log(response.text);
  } catch (error) {
    console.log('Ooops, ', error.message); //  Promise !}}
  }
}

여기서 리퀘스트의 작법은 일반적인 Promise 비동기적인 작법이다.gen에서 비동기적인 작법은 이미 매우 동기화되었다. 유일한 단점은 중간에 있는 이 코드가 우리가 여러 번 비동기적일 때 우리는 끊임없이 연장해야 한다는 것이다.
function request(){
// , 
}
let it = gen();
let p = it.next().value;
// res it.next(res).value, promise , promise.then() 
p.then(res => it.next(res).value, err => it.throw(err))        
  .then(res => it.next(res).value, err => it.throw(err));

function* gen() {
  try {
    let response = yield request();
    console.log(response);
    let response2 = yield request();
    console.log(response,response2);
  } catch (error) {
    console.error('Ooops', error); //  Promise !}}
  }
}

이렇게 하면 아름답지 않겠습니까? 어쨌든 계속 중복된 코드를 써야 합니다.그래서 우리는generator가 자동으로 달리는 것을 보조하는 함수를 하나 더 쓴다.
//generator  , generator yield  promise 
let genRun = function () {
  function run(p, gen) {
    p.then(resolve => {
      p = gen.next(resolve).value;
      if (p !== undefined) {
        run(p, gen)
      }
    }, reject => {
      p = gen.throw(reject).value;
    })
  }

  return function (generator) {
    let g = generator();
    run(g.next().value, g)
  }
}();

function request() {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      let num = Math.random();
      if (num > 0.8) {
        reject(num + "request err")
      } else {
        resolve(num * 100);
      }
    }, 100)
  })
}


genRun(function* () {
  try {
    let response1 = yield request();
    console.log("response1", response1);
    let response2 = yield request();
    console.log("response2", response2);
    let response3 = yield request();
    console.log("response3", response3);
  } catch (e) {
    console.error(e)
  }
});

이렇게 하면 우리가 request가 되돌아오는 것을 보증하기만 하면 된다Primise 대상은 우리의 비동기 코드를 이상하게 쉽게 쓸 수 있다.
이 글은 설명된 주석이 많지 않다. 주로 요 며칠 동안 너무 피곤했기 때문이다. 나중에 시간이 나면 다시 돌아와서 이해를 보조하는 주석을 보충하고 관나리께서 저에게 계속 쓸 수 있도록 칭찬과 격려를 해 주십시오.

좋은 웹페이지 즐겨찾기