분류 javascript

비동기(async) JS에 대한 시각적 학습자 안내서

컨텐츠 정보

  • 조회 187 (작성일 )

본문

몇 시간 분량의 자습서를 보거나 읽었지만 여전히 혼란스러웠습니까? 비동기 JavaScript를 처음 배우게 되었을 때의 느낌입니다. 나는 promises과 async/await의 차이점을 분명히 보기 위해 애를 썼습니다. 특히 두려운 점이 같기 때문에.


https://blog.logrocket.com/the-visual-learners-guide-to-async-js-62a0a03d1d57/ 


비동기 JS는 수년에 걸쳐 많은 발전을 거듭했습니다. 자습서는 훌륭하지만 종종 특정 시점에서 일을 하는 "올바른"방법의 스냅샷을 제공합니다. 콘텐츠의 날짜에 주의를 기울여야 한다는 사실을 깨닫지 못하고 서로 다른 구문을 함께 섞어 보았습니다. 가장 최근의 컨텐트만 소비하려고 했는데도 여전히 뭔가 빠져 있었습니다.


나는 내 학습 스타일에 말을 하지 않는 많은 자료를 깨달았습니다. 저는 시각적인 학습자입니다. 그래서 모든 다른 비동기 메소드를 이해하기 위해서, 저는 비주얼 스타일로 이야기하는 방식으로 모든 것을 함께 구성해야 했습니다. 여기서는 비동기에 관한 질문과 예제 및 비유를 통해 약속과 비동기를 차별화하는 방법에 대해 설명합니다.


왜 비동기가 필요한가요? 


JavaScript는 동기식 블로킹, 단일 스레드 언어입니다. 그 단어가 당신에게 별로 의미가 없다면, 이 시각적은 비동기 JS가 더 시간 효율적일 수 있는 방법을 더 잘 이해하는 데 도움이 되었습니다.


1*DyHHjRYX8soqgtO_b3y15Q.png?ssl=1 

굵은 선 = 프로그램이 정상적으로 실행되는 시간. 가는 선 = 네트워크를 기다리는 데 소요 된 시간. 


백그라운드에서 발생할 수 있는 일에 비동기 메서드를 사용하려고 합니다. 데이터베이스에서 항목을 쿼리 하거나 API 요청을 하는 동안 전체 앱이 기다리는 것을 원하지는 않습니다. 실제로는 세탁기가 끝날 때까지 전화 통화, 식사 금지, 화장실 이용 금지 등 아무것도 할 수 없는 것과 같습니다. 이것은 이상적이지 않습니다.


상자 밖에서 JS는 동기식이지만 비동기적으로 동작 할 수 있는 방법이 있습니다.


비동기의 진화 


"async JS"를 온라인으로 검색 할 때 콜백, promises 및 async/await와 같은 여러 가지 구현이 있었습니다. 일관된 구문으로 코딩 할 수 있도록 각 방법과 고유한 가치 제안에 대해 명확히 하는 것이 중요했습니다. 다음은 각 항목에 대한 설명입니다.


Callbacks 


ES6 이전에는 콜백을 사용하여 이 비동기 동작을 구현했습니다. 간단히 말해 콜백은 현재 함수가 실행 완료되면 실행될 다른 함수에 매개 변수로 보내는 함수입니다. 사람들이 이것을 "콜백 지옥"이라고 부르는 이유가 있다고 합시다.


콜백을 사용하여 이벤트의 순서를 제어하려면 다른 함수의 콜백 내에 함수를 중첩하여 원하는 순서대로 함수가 생성되도록 해야 합니다.


1*dQgkS279Z-xzfK0rkBBP2A.png?ssl=1 

"콜백 지옥."


이것을 구현하면 모든 두통이 생겼으므로 JS 커뮤니티는 promise 객체를 생각해 냈습니다.


Promises 


인간으로서 동기식 코드를 이해하고 읽는 것이 더 쉽기 때문에 동기식으로 보이지만 비동기식으로 작동하도록 약속이 만들어졌습니다. 이상적으로는 다음과 같이 보일 것입니다.


1*vHdVwZOQCGyX-RIK4NJwqQ.png?ssl=1 


멋지게 보일지 모르지만 몇 가지 핵심 요소가 누락되어 있는데 그 중 하나는 오류 처리입니다. 처리되지 않은 약속 거부 오류 또는 경고를 받은 적이 있습니까? 일부 오류가 발생하여 약속이 해결되는 대신 거부되었습니다.


위의 스니펫에서는 "성공"의 경우만 처리합니다. 이는 처리되지 않은 약속이 해결되지 않으며 메모리가 차지하는 메모리가 해제되지 않음을 의미합니다. 조심하지 않으면 catch를 사용하여 수동으로 처리하지 않는 한 약속은 자동으로 실패합니다.


1*uvHdR3kMsJtdfPamlgkS7Q.png?ssl=1 


Async/await 


이것은 약속 위에 있는 구문 설탕으로, 코드를 더 읽기 쉽게 보이게 합니다. 함수 앞에 "async"키워드를 추가하면 특성이 변경됩니다.


비동기 함수는 promise 내에서 값을 반환합니다. 해당 값에 액세스하려면 메소드를 .then()해야 하거나 기다려야(await)합니다.


스타일과 규칙 외에도, 비동기 동작을 구현하기 때문에 코드에서 서로 다른 비동기 메서드를 함께 사용하는 것이 기술적으로 좋습니다. 그러나 각각의 차이점을 완전히 이해하면 망설임 없이 일관된 구문으로 글을 쓸 수 있습니다.


async / await은 promises을 사용하기 때문에 초기에는 구문과 규칙의 관점에서 두 가지 방법을 분리하려고 애썼습니다. 그들 사이의 차이점을 정리하기 위해 각각의 사용 사례에 대해 각 메소드와 구문을 매핑했습니다.


promises 및 async/await 비교 


이러한 비교는 내가 원래 매핑 한 것의 시각적으로 업그레이드 된 버전입니다. Promises은 왼쪽에 있고, 오른쪽에 async / await입니다.


Consuming 


1*C6B05ty6ltEtKgS_FEp0Aw.png?ssl=1 


getJSON()은 promise을 반환하는 함수입니다. promise을 위해서는 promise을 해결하기 위해 다음을 수행해야 합니다. promise을 해결하는 또 다른 방법은 그것을 기다리는 것입니다.


N.B., "await"는 비동기 함수 내에서만 호출 할 수 있습니다. 여기서 비동기 함수는 두 방법을 보다 직접 비교하기 위해 생략되었습니다.


Creating 


1*PbuSmkWo3D5jSr39bbiBgQ.png?ssl=1 

이 두 가지 모두 Promise {<resolved> : "hi"}를 반환합니다. async를 사용하면 명시 적으로 약속을 반환하지 않아도 코드가 약속을 지키게 됩니다.


resolve()는 promise에 대한 executor 함수 중 하나입니다. 호출되면 값으로 해결 된 promise 객체를 반환합니다. 이 동작을 직접 비교하기 위해 비동기 메소드는 즉시 호출 된 함수로 래핑 됩니다.


Error handling 


1*i1yzaTVK1YO99kzvUn4vjQ.png?ssl=1 


오류를 잡는 몇 가지 방법이 있습니다. 하나는 then/catch를 사용하는 것이고 다른 하나는 try / catch를 사용하는 것입니다. 두 방법 모두 약promises과 async/await와 교환하여 사용할 수 있지만, 각각 가장 일반적으로 사용되는 규칙 인 것 같습니다.


"async/await"사용의 주요 이점은 오류 스택 추적에 있습니다. 약속을 통해 B가 해결되면 스택 추적에서 A에 대한 컨텍스트가 더 이상 존재하지 않습니다. 따라서 B 또는 C 예외를 던지면 더 이상 A의 상황을 알 수 없습니다.


그러나 async/await를 사용하면 B가 해결되기를 기다리는 동안 A가 일시 중단됩니다. 따라서 B 나 C가 예외를 던지면 스택 추적에서 A가 오류임을 알 수 있습니다.


Iterating 


1*R5Im4AOl01u-0UY78ieSXw.png?ssl=1 


구문의 차이점을 더 명확하게 볼 수 있도록 여기에 이름에 단일 문자를 사용하고 있습니다. 전에 코드 샘플을 읽었을 때 함수 이름의 잡초를 두드려서 무슨 일이 일어 났는지 알았습니다. 특히 시각적인 학습자로서 그것은 나에게 산만 해졌습니다.


참고로, 각 작업이 비동기 적이지만 둘 다 작업을 동시에 실행하지는 않습니다. 아래의 "병렬 실행"에서 이 부분을 설명하겠습니다.


Testing 


1*5KunRgOF8I6aWf9hpjWGcQ.png?ssl=1 


미묘하지만 중요한 차이점이 있습니다. 비동기 함수는 약속을 반환한다는 점을 기억하십시오. 마찬가지로 정규 약속을 사용하는 경우 이를 반환해야 합니다.


참고할 사항 :

  • 일부 비동기 앞에 기다리는 것이 미해결 된 약속을 초래하지 않으므로 테스트 결과가 거짓 긍정을 반환하게 됩니다.
  • 약속을 반환하는 비동기 메서드를 스텁하려는 경우 다음과 같이 할 수 있습니다.

1*z0GJsfL3ltDmiQXakiT1OA.png?ssl=1 


이제 대부분의 기본 시나리오를 다루었으므로 비동기와 관련된 고급 주제를 몇 가지 살펴 보겠습니다.


Parallel vs. sequential async 


async/await는 구문을 읽기 쉽도록 하기 때문에 병렬로 또는 순차적으로 실행되는 시점을 알려주는 것이 혼동 될 수 있습니다. 차이점은 다음과 같습니다.


Parallel execution 


하루 종일 해야 할 일이 있다고 가정 해 봅시다. 우편물을 가져오고, 빨래를 하고, 이메일에 응답합니다. 이들 중 어느 것도 서로 의존하지 않으므로 Promise.all()을 사용하여 각 작업을 실행할 수 있습니다. Promise.all()은 (반복 가능 한) 약속의 배열을 가져 와서 모든 비동기 메소드가 해결되거나 그 중 하나가 거부되면 거부합니다.


1*aAAOgSzoSOWqlMAp8GaeoA.png?ssl=1 


Sequential execution 


또는 서로 의존적인 작업이 있는 경우 순서대로 실행할 수 있습니다. 예를 들어 세탁을 한다고 가정 해 보겠습니다. 세탁, 건조, 접기 순서대로 해야 합니다. 세 가지를 동시에 수행 할 수는 없습니다. 주문이 있으므로 다음과 같이하십시오.


1*zX1r9QoYPQ-zdz9Idqro5A.png?ssl=1 

이 함수는 여기에서 리턴 값이 다음 함수의 입력으로 사용되기 때문에 순서대로 실행됩니다. 따라서 함수는 실행을 계속하기 위해 값이 반환 될 때까지 기다려야 합니다.


성공을 위한 팁 


누구나 다른 학습 스타일을 가지고 있습니다. 얼마나 많은 자습서를 보았든 또는 내가 읽은 블로그 게시물을 게시 했는지에 상관없이 내 비동기식 지식에는 여전히 구멍이 있었습니다. 내가 앉아서 모든 것을 매핑 했을 때만 마침내 조각들을 모았습니다.


어려움을 겪고 있는 개념을 접할 때 좌절하거나 실망하지 마십시오. 단순히 학습 스타일에 맞는 방식으로 정보가 제공되지 않기 때문입니다. 자료가 없으면 직접 만들고 공유하십시오! 얼마나 많은 사람들이 당신과 같은 느낌을 갖고 있는지 당신을 놀라게 할 수 있습니다.