JS co 함수 라 이브 러 리 의 의미 와 용법 실례 총결산

본 고의 실례 는 JS co 함수 라 이브 러 리 의 의미 와 용법 을 서술 하 였 다.여러분 께 참고 하도록 공유 하 겠 습 니 다.구체 적 으로 는 다음 과 같 습 니 다.
완 일 봉 선생님 의 비동기 프로 그래 밍 4 부작 의 3:co 를 계속 공부 합 니 다.
co 는 아주 오래 전에 초 형 에 게 들 었 는데 node 프로 그래 밍 에서 대량으로 사용 되 고 소스 코드 는 간단 하지만 생각 이 강하 다 고 말 했다.
시간 나 면 빨리 알 아 보 겠 습 니 다.얼마 전에 이 직 한 일 을 이리 저리 뛰 어 다 니 느 라 힘 들 었 습 니 다.
이제 야 모든 것 이 정상 으로 돌 아 왔 고 새로운 회사 의 리듬 에 필사적으로 적응 하고 있다.주말 을 틈 타 공 부 를 계속 할 수 밖 에 없다.
자,헛소리 하지 마 세 요.주제 로 돌아 갑 니 다.앞의 두 글 에서 우 리 는 각각 Generator 함수 와 Thunk 방식 의 자동 집행 을 배 웠 습 니 다.
오늘 우 리 는 지난번 의 사고방식 에 이 어 co 도 구 를 사용 하여 Generator 함수 의 자동 실행 을 실현 하 는 것 을 배 웠 다.
지난 절의 예 시 를 다시 꺼 냅 니 다.

var fs = require('fs');
var thunkify = require('thunkify');
var readFile = thunkify(fs.readFile);
 
var gen = function* (){
 var r1 = yield readFile('/etc/fstab');
 console.log(r1.toString());
 var r2 = yield readFile('/etc/shells');
 console.log(r2.toString());
};

이 코드 는 두 개의 파일 을 읽 는 데 사 용 됩 니 다.어떻게 co 도 구 를 사용 하여 자동 으로 실행 합 니까?
아주 간단 합 니 다.

var co = require('co');
co(gen);

위의 코드 에 서 는 Generator 함 수 를 co 함수 에 전달 하면 자동 으로 실 행 됩 니 다.
co 함 수 는 Promise 대상 을 되 돌려 줍 니 다.따라서 then 방법 으로 리 셋 함 수 를 추가 할 수 있 습 니 다.Generator 실행 이 끝나 면 리 셋 이 실 행 됩 니 다.

co(gen).then(function (){
 //success
});

이렇게 보면 우리 이전의 Thunk 방식 과 많이 다 르 지 않 은 것 같 아 요.run 함수 이름 만 co 로 바 꿨 어 요.
유일한 차이 점 은 Promise 포장 을 한 겹 더 한 것 이다.그렇다면 코 와 Thunk 는 어떤 차이 가 있 을 까?
우리 가 추측 한 바 와 같이 코 는 이전의 두 가지 자동 실행 방식(Thunk 와 Promise)을 결합 하여 하나의 라 이브 러 리 로 포장 한 것 이다.
이 를 사용 하 는 전제 와 Thunk 보다 Promise 가 많은 경우,즉 yield 반환 값 은 Thunk 함수 와 Promise 대상 중 하나 여야 합 니 다.
실현 원리:
이전에 우리 가 Thunk 함 수 를 연구 할 때 첫 번 째 단 계 는 thunkify 를 사용 하여 readFile 을 Thunk 함수 로 포장 하 는 것 이다.
오늘 우 리 는 Promise 를 연구 하려 면 readFile 을 Promise 대상 으로 포장 하고 코드 를 봐 야 한다.

var fs = require('fs');
 
var readFile = function (fileName){
 return new Promise(function (resolve, reject){
  fs.readFile(fileName, function(error, data){
   if (error) reject(error);
   resolve(data);
  });
 });
};
 
var gen = function* (){
 var f1 = yield readFile('/etc/fstab');
 var f2 = yield readFile('/etc/shells');
 console.log(f1.toString());
 console.log(f2.toString());
};

다음은 제 가 선생님 께 서 하 시 는 일 을 특히 좋아 합 니 다.먼저 가장 원시 적 인 방식 으로 코드 를 수 동 으로 실행 하 겠 습 니 다.
우리 가 일상적으로 개발 하 는 과정 에서 도 이런 방식 을 참고 할 수 있다.논리 가 복잡 할 때 가장 솔직 한 방식 으로 그것 을 실현 하 는 것 도 좋다.
그리고 안에 있 는 규칙 을 발견 하고 재 구성 을 최적화 시킨다.또 시작 되 었 습 니 다.수 동 으로 실행 되 는 코드 를 보 세 요.

var g = gen();
 
g.next().value.then(function(data){
 g.next(data).value.then(function(data){
  g.next(data);
 });
});

수 동 으로 실행 하 는 것 은 바로 then 방법 으로 층 층 이 리 셋 함 수 를 추가 하 는 것 이다.이 점 을 이해 하면 자동 실행 기 를 쓸 수 있 습 니 다.

function run(gen){
 var g = gen();  //    
 
 function next(data){
  var result = g.next(data);
  if (result.done) return result.value;
  result.value.then(function(data){
   next(data);
  });
 }
 next();
}
run(gen);

Thunk 함수 와 의 차 이 는 Thunk 함수 가 실행 에 성공 한 후에 next 를 thunkify 에 게 전달 하고 thunkify 가 next 를 수행 하 는 것 을 도와 주 는 것 입 니 다.
여기 방법 이 그 렇 죠?next 는 Promise 에 게 맡 기 고 promise 제어 요청 이 성공 할 때 next 를 실행 합 니 다.차이 점 은 이 정도 밖 에 없다.
원 리 를 분석 한 후에 우 리 는 co 의 소스 코드 를 분석 했다.
co 함수 가 Generator 인 자 를 받 아들 여 Promise 대상 을 되 돌려 줍 니 다.

function co(gen) {
 var ctx = this;
 
 return new Promise(function(resolve, reject) {
 });
}

돌아 오 는 Promise 대상 에서 인자 gen 이 Generator 함수 인지 확인 합 니 다.만약 그렇다면 이 함 수 를 실행 하여 내부 포인터 대상 을 얻 습 니 다.
아니면 되 돌려 주 고 Promise 대상 의 상 태 를 resolved 로 변경 합 니 다.

function co(gen) {
 var ctx = this;
 
 return new Promise(function(resolve, reject) {
  if (typeof gen === 'function') gen = gen.call(ctx);
  if (!gen || typeof gen.next !== 'function') return resolve(gen);
 });
}

이 어 코 는 next 방법 을 포장 하여 이상 이 드 러 날 수 있 도록 한다.

function co(gen) {
 var ctx = this;
 
 return new Promise(function(resolve, reject) {
  if (typeof gen === 'function') gen = gen.call(ctx);
  if (!gen || typeof gen.next !== 'function') return resolve(gen);
 
  onFulfilled();
  function onFulfilled(res) {
   var ret;
   try {
    ret = gen.next(res);
   } catch (e) {
    return reject(e);
   }
   next(ret);
  }  
 });
}

마지막 으로 next 방법 입 니 다.

function next(ret) {
 if (ret.done) return resolve(ret.value);
 var value = toPromise.call(ctx, ret.value);
 if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
 return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '
    + 'but the following object was passed: "' + String(ret.value) + '"'));
  }
});

next 방법의 가장 중요 한 줄:

if (value && isPromise(value)) return value.then(onFulfilled, onRejected);

co 의 사용 조건,매번 yield 반환 은 Promise 대상 이 어야 합 니 다.promist 처리 가 성공 할 때 onFulfilled 를 다시 실행 합 니 다.
이로써 자동 집행 의 효과 에 도달 하 다.
co 는 동시 다발 적 인 비동기 작업 도 지원 합 니 다.yield 는 배열 이나 옮 겨 다 니 는 대상 을 되 돌려 주면 됩 니 다.

//      
co(function* () {
 var res = yield [
  Promise.resolve(1),
  Promise.resolve(2)
 ];
 console.log(res); 
}).catch(onerror);
 
//      
co(function* () {
 var res = yield {
  1: Promise.resolve(1),
  2: Promise.resolve(2),
 };
 console.log(res); 
}).catch(onerror);

이로써 co 의 자동 집행 원 리 는 우리 가 이미 배 웠 다.
사실은 본질 적 으로 어렵 지 않 지만 관련 된 모듈 이 비교적 많 고 사고 방향 이 비교적 유연 하 다.
나의 소 용량 뇌 에 있어 서 현재 의 인식 은 아직 90%에 불과 하 다.
그래서 이 글 에서 자신의 사상 이 비교적 적 고 더 많은 것 은 선생님 의 생각 을 복창 하 는 것 이다.
마지막 으로 원문의 주 소 를 붙인다.co 함수 라 이브 러 리 의 의미 와 용법
관심 있 는 친 구 는 온라인 HTML/CSS/JavaScript 코드 실행 도 구 를 사용 할 수 있 습 니 다.http://tools.jb51.net/code/HtmlJsRun상기 코드 실행 효 과 를 테스트 할 수 있 습 니 다.
더 많은 자 바스 크 립 트 관련 내용 은 본 사이트 의 주 제 를 볼 수 있 습 니 다.
본 고 에서 말 한 것 이 여러분 의 자 바스 크 립 트 프로 그래 밍 에 도움 이 되 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기