async / await 와 generator 는 어떤 차이 가 있 습 니까?

async / await 는 es 2017 의 중요 한 새로운 특성 입 니 다.async / await 는 es 2015 에 발 표 된 generator 와 비슷 한 점 이 많다.stackoverflow 는 이 두 가지 다른 점 에 대한 질문 이 많 습 니 다. 에서 도 좋 은 대답 이 있 었 다.만약 당신 이 co 모듈 을 사용 한 적 이 있다 면, generator 기반 코드 는 async / await 처럼 보일 것 입 니 다.
다음은 async / await 에서 HTTP 요청 을 세 번 처리 합 니 다.
async function test() {
  let i
  for (i = 0; i < 3; ++i) {
    try {
      await superagent.get('http://google.com/this-throws-an-error')
      break
    } catch (err) {}
  }
  console.log(i) // 3
}

같은 기능 의 generator 구현:
const test = co.wrap(function*() {
  let i
  for (i = 0; i < 3; ++i) {
    try {
      yield superagent.get('http://bad.domain')
      break
    } catch (err) {}
  }
  console.log(i) // 3
})

관찰 을 통 해 async / await 를 generator 로 바 꾸 는 컨버터 를 쓸 수 있 습 니 다. 원 리 는 async function() {}co.wrap(function*() {}) 로 바 꾸 고 awaityield 로 바 꾸 는 것 입 니 다.그래서 이 두 가 지 는 도대체 어떤 차이 가 있 습 니까?
차이 점
중요 한 것 은 generator 가 Node. js 4. x 지원 시작 에 있 고 async / await 요구 Node. js > = 7.6.0 에 있다 는 것 이다.그러나 Node. js 4. x 는 이미 유지 하지 않 았 고 Node. js 6. x 도 2019 년 에 유지 보 수 를 중 지 했 기 때문에 이 차이 점 은 지금 그다지 중요 하지 않다.
다른 하 나 는 co 모듈 은 개발 자가 유지 하 는 제3자 모듈 이 고 async / await 는 js 언어의 일부분 입 니 다.그래서 package. json 에 co 를 써 야 합 니 다. async / await 는 필요 하지 않 습 니 다. 하지만 오래된 브 라 우 저 를 지원 하려 면 컨버터 를 설정 해 야 합 니 다.
stack traces 에서 얻 은 오류 가 다 릅 니 다.async / await 에서 얻 은 오 류 는 generator 보다 뚜렷 합 니 다.그리고 async / await 는 JavaScript 언어의 핵심 부분 이지 co 와 같은 사용자 급 라 이브 러 리 가 아니 기 때문에 앞으로 async / await 스 택 추적 을 더 개선 할 수 있 습 니 다.
async 함수 가 던 진 오 류 를 보 여 주 는 예 가 있 습 니 다.
async function runAsync() {
  await new Promise(resolve => setTimeout(() => resolve(), 100))
  throw new Error('Oops!')
}

// Error: Oops!
//    at runAsync (/home/val/test.js:5:9)
//    at 
runAsync().catch(error => console.error(error.stack))

다음은 generator 로 이 루어 진 같은 기능 입 니 다. 오류 에 나타 난 onFulfilled()Generator.next() 이 새 는 것 을 주의 하 십시오 co 모듈 은 어떻게 작 동 합 니까?.
const co = require('co')

const runCo = co.wrap(function*() {
  yield new Promise(resolve => setTimeout(() => resolve(), 100))
  throw new Error('Oops!')
})

// Error: Oops!
//     at D:\code\js\test\babel-test\src\co_test.js:5:9
//     at Generator.next ()
//     at onFulfilled (D:\code\js\test\babel-test
ode_modules\co\index.js:65:19) runCo().catch(error => console.error(error.stack))

Thunks 와 Promise 전환
async / await 는 Promise 에 만 사 용 됩 니 다. 비 Promise 에 사용 하면 소 용이 없습니다.
async function runAsync() {
  // res       function
  //    function    promise,           
  const res = await (cb => cb(null, 'test'))
  console.log(res)
}

runAsync().catch(error => console.error(error.stack))

다른 한편, 코 는 yield 의 값 을 Promise 로 바 꿉 니 다.yield Node. js 스타일 의 리 셋 함수 가 되면 코 는 그것 을 promise 로 바 꿀 것 이다.
const co = require('co')

const runCo = co.wrap(function*() {
  // `res` will be a string, because co converts the
  // value you `yield` into a promise. The `yield cb => {}`
  // pattern is called a _thunk_.
  const res = yield cb => cb(null, 'test')
  console.log(res)
})

runCo().catch(error => console.error(error.stack))

마찬가지 로 코 도 비슷 한 효 과 를 낼 수 있다.
async function runAsync() {
  //   co   ,    
  // `yield [Promise.resolve('v1'), Promise.resolve('v2')]`
  const res = await Promise.all([
    Promise.resolve('v1'),
    Promise.resolve('v2');
  ]);
  // 'v1 v2'
  console.log(res[0], res[1]);
}

제3자 창고 의 장점
많은 경우 에 generator 는 async / await 의 초 집합 이다.generator 를 사용 하면 강력 한 특성 을 사용 하여 자신의 async / await 로 전환 할 수 있 습 니 다. Co 에 내 장 된 Promise 전환 은 빙산 의 일각 일 뿐 입 니 다.예 를 들 어 나 는 일찍이 하 나 를 세 웠 다 코 와 같은 라 이브 러 리 입 니 다. 이 라 이브 러 리 는 관찰 가능 한 대상 을 되 돌려 줍 니 다..RxJS 의 filter 연산 자 를 사용 하면 오 류 를 처리 하 는 것 이 매우 쉬 울 것 입 니 다.
const corx = require('./')
require('rxjs/add/operator/filter')

corx(function*() {
  yield Promise.resolve('Test 1')
  try {
    yield Promise.reject('Test 2')
  } catch (error) {}
  console.log('Reached the end')
})
  .filter(v => !!v)
  .subscribe(
    op$ => {
      // This will print, even though the error was caught, because
      // this callback executes on every single async operation!
      op$.subscribe(
        () => {},
        err => console.log('Error occurred', err)
      )
    },
    error => console.log('This will not print'),
    () => console.log('Done')
  )

위의 슬 레이 어 즈 급 기능 은 subscribe () 가 있 을 때 generator 함수 에서 발생 하 는 모든 비동기 작업 이 하나의 반전 을 얻 는 것 입 니 다.이것 은 모든 논 리 를 실제 적 으로 변경 하지 않 은 상태 에서 debugging, profiling, error handling 을 통 해 모든 단독 비동기 작업 을 검사 할 수 있 음 을 의미 합 니 다!
이 특성 은 매우 멋 있 지만, async / await 용 generator 를 버 리 기 에는 부족 합 니 다.async / await 의 장점 은 대부분의 시간 동안 당신 의 요 구 를 만족 시 키 는 데 있 습 니 다. 이 observable 기반 라 이브 러 리 는 실제 적 으로 어떤 문 제 를 해결 해 줄 것 입 니까?디 버 깅 을 위해 서 는 관찰 가능 한 Promise.all() 에서 의미 있 는 정 보 를 추출 하 는 방법 이 필요 할 것 입 니 다. 일반적인 상황 에서 저 는 이런 방법 을 제외 하고 다른 방법 을 찾 지 못 했 습 니 다.
이것 이 바로 내 가 다시 middleware 를 중시 하고 이 를 분야 간 문 제 를 해결 하 는 정확 한 도구 로 삼 아야 하 는 이유 이다.
또한, async / await 의 적용 상황 에 대해 관찰 대상 은 좋 은 선택 이 아 닐 수 있 습 니 다. 여러 값 으로 해석 되 고 무한 값 의 순환 으로 해석 되 기 때 문 입 니 다.
총결산
async / await 와 generator 는 언뜻 보기 에는 비슷 하지만 이들 사이 에는 의미 있 는 차이 가 많다.
async / await 는 제3자 라 이브 러 리 가 필요 없 이 더욱 간결 해 보 입 니 다.generator 는 일반적으로 제3자 라 이브 러 리 에 맞 춰 사용 해 야 하지만, 이러한 제3자 라 이브 러 리 는 async / await 가 갖 추 지 못 한 강력 한 기능 을 많이 제공 합 니 다.다시 말 하면 async / await 와 generator 사이 의 균형 은 간결 함 과 유연성 사이 의 균형 이다.
고급 개발 자로 서 당신 은 어떤 상황 에서 개발 자 에 게 서 의미 있 는 가 치 를 얻 을 수 있 지만, 대부분의 경우 async / await 가 더 좋 은 선택 입 니 다.

좋은 웹페이지 즐겨찾기