async / await 와 generator 는 어떤 차이 가 있 습 니까?
다음은 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*() {})
로 바 꾸 고 await
를 yield
로 바 꾸 는 것 입 니 다.그래서 이 두 가 지 는 도대체 어떤 차이 가 있 습 니까?차이 점
중요 한 것 은 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 가 더 좋 은 선택 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Thymeleaf 의 일반 양식 제출 과 AJAX 제출텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.