《 async / await 는 양날 의 검 》 을 정독 하 다.
5510 단어 자바 script
머리말
드디어 async / await 도 토로 되 었 다.Aditya Agarwal 은 async / await 문법 이 우 리 를 새로운 문제 에 빠 뜨 렸 다 고 생각 합 니 다.
사실 필 자 는 어디 가 이상 하 다 고 생각 했 습 니 다. 드디어 누군가가 진실 을 말 했 습 니 다. async / await 는 문 제 를 일 으 킬 수 있 습 니 다.
개술
다음은 어디서나 볼 수 있 는 현대화 전단 코드 입 니 다.
(async () => {
const pizzaData = await getPizzaData(); // async call
const drinkData = await getDrinkData(); // async call
const chosenPizza = choosePizza(); // sync call
const chosenDrink = chooseDrink(); // sync call
await addPizzaToCart(chosenPizza); // async call
await addDrinkToCart(chosenDrink); // async call
orderItems(); // async call
})();
await 문법 자체 에 문제 가 없고 사용자 가 잘못 사용 한 것 일 수도 있 습 니 다.
pizzaData
와 drinkData
사이 에 의존 하지 않 을 때 순서 적 인 await 는 실행 시간 을 최대 배로 늘 리 는 getPizzaData
함수 시간 입 니 다. getPizzaData
과 getDrinkData
을 병행 해 야 하기 때 문 입 니 다.우리 가 토로 한 리 턴 지옥 으로 돌아 가면 코드 가 비교적 못 생 겼 지만 적어도 두 줄 의 리 턴 코드 를 가지 고 가 는 것 은 막 히 지 않 을 것 이다.
보아하니 문법의 간소화 가 성능 문 제 를 가 져 왔 고 사용자 체험 에 직접적인 영향 을 미 쳤 으 니 우리 가 반성 해 볼 필요 가 있 지 않 겠 는가?
정확 한 방법 은 먼저 함 수 를 동시에 실행 한 다음 에 await 값 을 되 돌려 야 합 니 다. 이렇게 하면 비동기 함 수 를 병행 할 수 있 습 니 다.
(async () => {
const pizzaPromise = selectPizza();
const drinkPromise = selectDrink();
await pizzaPromise;
await drinkPromise;
orderItems(); // async call
})();
또는 사용
Promise.all
코드 를 더 읽 을 수 있 습 니 다.(async () => {
Promise.all([selectPizza(), selectDrink()]).then(orderItems); // async call
})();
코드 성능 을 떨 어 뜨 릴 수 있 습 니 다.
정독
왜 async / await 가 남용 되 었 는 지 곰 곰 이 생각해 보면 필 자 는 그의 기능 이 비교적 반 직각 으로 인 한 것 이 라 고 생각한다.
우선 async / await 는 정말 문법 사탕 이 고 기능 도 코드 를 편 하 게 쓰 는 것 에 불과 합 니 다.먼저 그의 문법 이나 특성 을 보지 않 고 문법 사탕 세 글자 만 보면 특정한 능력 을 제한 한 것 임 을 알 수 있다.
예 를 들 어 우 리 는 html 라벨 을 이용 하여 구성 요 소 를 봉 하여 편리 성 을 가 져 오 는 동시에 그 기능 은 반드시 html 의 부분 집합 이다.또한, 어떤 바퀴 형 은 특정한 구성 요소 api 가 너무 복잡 하 다 고 생각 하기 때문에 이 를 바탕 으로 문법 사탕 을 봉 했다. 우 리 는 대부분 이 편리 성 이 일부 기능 을 희생 하여 바 꾼 것 이 라 고 생각 할 수 있다.
기능 의 완전 도와 사용 편의 도 는 서로 게임 을 해 왔 고 많은 구조 사상의 서로 다른 오픈 소스 버 전 은 기능 의 완전 도와 편리 도 를 서로 다른 비례 에 따라 혼합 한 결과 이다.
그럼 async / await 로 돌아 가 해결 하 는 문 제 는 지옥 으로 돌아 가 는 재난 입 니 다.
a(() => {
b(() => {
c();
});
});
내장 구조 가 너무 많아 뇌 에 미 치 는 충격 을 줄 이기 위해 async / await 는 이렇게 쓰기 로 했다.
await a();
await b();
await c();
등급 은 일치 하지만 논리 적 으로 는 포 함 된 관계 로 어느 정도 뇌 부담 을 증가 시 키 지 않 았 을 까?그리고 이 전환 은 스텔스 이기 때문에 우 리 는 이 를 무시 하 는 경향 이 많아 문법 사탕 의 남용 을 초래 했다.
이해 문법 사탕
async / await 의 실제 효과 가 반 인간 적 이라는 것 을 정확하게 이해 해 야 하지만 시원 한 코드 구조 와 저 성능 코드 를 쓰 는 것 을 방지 하기 위해 서 는 async / await 가 가 져 온 변 화 를 진지 하 게 이해 할 필요 가 있다.
우선 async / await 는 일부 반전 지원 기능 만 실현 할 수 있 습 니 다. 즉, 레이 어 링 장면 에 만 편리 하 게 대응 할 수 있 습 니 다.다른 장면 은 머리 를 좀 써 야 겠 다.
예 를 들 어 두 쌍 의 반전:
a(() => {
b();
});
c(() => {
d();
});
아래 의 방식 으로 쓰 면 기능 이 일치 하 는 것 을 보장 할 수 있 지만 가장 낮은 실행 방식 이 됩 니 다.
await a();
await b();
await c();
await d();
반전 으로 번역 되 었 기 때문에:
a(() => {
b(() => {
c(() => {
d();
});
});
});
그러나 원본 코드 에서 함수
c
는 a
와 동시에 실행 할 수 있 지만 async / await 문법 은 b
이 실 행 된 후에 실행 하 는 경향 이 있 음 을 발견 했다 c
.그래서 우리 가 이 점 을 깨 닫 게 되면 성능 을 최적화 시 킬 수 있다.
const resA = a();
const resC = c();
await resA;
b();
await resC;
d();
그러나 사실 이 논리 도 리 셋 의 효과 에 이 르 지 못 한다.
a
와 c
이 동시에 집행 되 었 지만 d
기 다 렸 다가 c
집행 시간 이 a
보다 길 면 다음 과 같다.a(() => {
d();
});
보아하니 완전히 두 함수 로 격 리 되 어야 할 것 같다.
(async () => {
await a();
b();
})();
(async () => {
await c();
d();
})();
또는 이용
c
:async function ab() {
await a();
b();
}
async function cd() {
await c();
d();
}
Promise.all([ab(), cd()]);
이것 이 바로 내 가 표현 하고 자 하 는 무 서운 점 이다.리 셋 방식 이 이렇게 간단 한 과정 식 코드 를 async / await 로 바 꾸 었 는데 다 쓰 고 나 서 다시 한 번 반성 하고 성능 을 최적화 하 는 것 은 리 셋 지옥 보다 더 무 서운 일이 다.
그리고 대부분의 장면 코드 는 매우 복잡 하 다. 동기 화 와 await 가 혼합 되 어 그 중의 맥락 을 정확하게 파악 하고 성능 을 정확하게 최적화 하 는 것 은 매우 어렵다.그런데 우 리 는 왜 스스로 구 덩이 를 파고 구 덩이 를 메 워 야 합 니까?잊 어 버 리 고 채 우 는 경우 가 많다.
원문 작 가 는
Promise.all
방식 으로 논 리 를 간소화 하 였 으 나 필 자 는 async / await 문법 을 추구 하지 말고 필요 한 상황 에서 리 셋 을 적당 하 게 사용 하면 코드 의 가 독성 을 증가 시 킬 수 있다 고 생각한다.총화
async / await 지옥 은 새로운 특성 에 지나치게 의존 하지 말 라 고 일 깨 워 준다. 그렇지 않 으 면 가 져 올 수 있 는 코드 의 실행 효율 이 떨 어 지고 사용자 체험 에 영향 을 줄 수 있다.또한 필 자 는 새로운 특성 을 이용 하여 새로운 특성 이 가 져 온 문 제 를 과도 적 으로 복원 하지 말 아야 코드 의 가 독성 이 떨어진다 고 생각한다.
내 가 redux 가 막 불 이 났 을 때의 오래된 코드 를 펼 쳤 을 때 과도 추상 적 이 고 사용 하기 위해 사용 하 는 코드 를 많이 보 았 다. 억지로 두 줄 코드 가 다 쓸 수 있 는 논 리 를 3 개의 파일 로 뜯 어서 6 줄 의 서로 다른 위치 에 분산 시 켰 다. 나 는 문자열 검색 방식 으로 단 서 를 찾 을 수 밖 에 없 었 다. 마지막 으로 이 추상 코드 전체 항목 이 한 번 밖 에 사용 되 지 않 았 다 는 것 을 발견 했다.
이런 코드 를 쓸 가능성 은 단 하나 다. 바로 정신 이 무감각 한 상태 에서 redux 가 제공 하 는 모든 닭 볶 음탕 을 단숨에 마 셨 다 는 것 이다.
async / await 지옥 처럼 이런 redux 코드 를 보면 시대 의 옛 전단 지 를 따라 가지 못 한 jquery 코드 보다 훨씬 못 하 다 고 생각 합 니 다.
코드 의 질 을 결정 하 는 것 은 구조 나 문법 이 아니 라 사고 입 니 다. async / await 는 좋 지만 적당 해 야 합 니 다.
5. 더 많은 토론
토론 주 소 는 'async / await 지옥 탈출' · Issue \ # 82 · dt - fe / weekly 정독
토론 에 참여 하고 싶다 면 여 기 를 클릭 하 세 요. 매주 새로운 주제 가 있 고 주말 이나 월요일 에 발표 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Thymeleaf 의 일반 양식 제출 과 AJAX 제출텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.