From 11ef2cb3d97ec1f01459e922176fdc51c9962be7 Mon Sep 17 00:00:00 2001 From: woohm402 Date: Thu, 12 Sep 2024 23:26:33 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B9=84=EB=8F=99=EA=B8=B0=20=EC=9E=90?= =?UTF-8?q?=EB=A3=8C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/lecture/src/App.tsx | 2 +- .../src/components/CodeSnippet/index.tsx | 3 +- .../lecture/src/lectures/ApiCall/lecture.tsx | 55 +++ .../src/lectures/Async/fetch-promise.png | Bin 0 -> 55600 bytes .../lecture/src/lectures/Async/lecture.tsx | 393 +++++++++++++++++- frontend/lecture/src/pages.tsx | 2 + 6 files changed, 451 insertions(+), 4 deletions(-) create mode 100644 frontend/lecture/src/lectures/ApiCall/lecture.tsx create mode 100644 frontend/lecture/src/lectures/Async/fetch-promise.png diff --git a/frontend/lecture/src/App.tsx b/frontend/lecture/src/App.tsx index 60ba3a7..acc63b8 100644 --- a/frontend/lecture/src/App.tsx +++ b/frontend/lecture/src/App.tsx @@ -45,7 +45,7 @@ const Sidebar = () => { const currentPath = useLocation().pathname; return ( -
+
{ return ( TBD
, + }, + { title: '(OT 복습) API 통신이란?', content:
TBD
}, + { title: '(OT 복습) HTTP', content:
TBD
}, + { title: '(OT 복습) JSON', content:
TBD
}, + { + title: 'json placeholder', + content: ( +
아쉽게도 우리는 백엔드가 아직 없으니 목서버를 사용합니다
+ ), + }, + { title: 'React 에서 API 통신하기', content:
TBD
}, + { + title: 'API 통신 시 주의할 점 (1) 처음에는 undefined 이다', + content:
TBD
, + }, + { + title: 'API 통신 시 주의할 점 (2) useEffect cleanup', + content:
TBD
, + }, + { + title: 'API 통신 시 주의할 점 (3) 내가 뭘 하려는 건지 잘 생각해보자', + content: ( +
+
+ Promise 를 벗기려고 무작정 await 을 때려도 해결되는 건 없다 +
+
+ ), + }, + { + title: 'todo list 만들어보기 라이브코딩', + content: ( +
+ https://jsonplaceholder.typicode.com 의 todo 목록을 버튼 클릭으로 + 왔다갔다 할 수 있는 코드 +
+ ), + }, + ]} + /> + ), +}); diff --git a/frontend/lecture/src/lectures/Async/fetch-promise.png b/frontend/lecture/src/lectures/Async/fetch-promise.png new file mode 100644 index 0000000000000000000000000000000000000000..9cd05111214ecd450941506e48a29e69d1ce8f78 GIT binary patch literal 55600 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%0D7O9c_ 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 MDP_rm7e;>n2Tdu5*#H0l literal 0 HcmV?d00001 diff --git a/frontend/lecture/src/lectures/Async/lecture.tsx b/frontend/lecture/src/lectures/Async/lecture.tsx index c57f206..69cc6bf 100644 --- a/frontend/lecture/src/lectures/Async/lecture.tsx +++ b/frontend/lecture/src/lectures/Async/lecture.tsx @@ -1,9 +1,14 @@ +import { Callout } from '@/components/Callout'; import { CodeSnippet } from '@/components/CodeSnippet'; import { Description } from '@/components/Description'; import { InlineCode } from '@/components/InlineCode'; +import { AssetDescriptionLayout } from '@/components/SlideLayout'; import { Slides } from '@/components/Slides'; +import { Button } from '@/designsystem/ui/button'; import { getLectureItem } from '@/lectures'; +import fetchPromise from './fetch-promise.png'; + export const asyncLecture = getLectureItem({ title: '비동기', description: 'callback, Promise, event loop', @@ -90,16 +95,400 @@ export const asyncLecture = getLectureItem({ { title: '왜 비동기로 동작해야 할까', content: ( -
+

느리니까

-
    +
    • API 요청
    • File System I/O
    • "1초 대기" 스펙
    +

    + 브라우저가 API 응답을 기다리는 동안 +
    + 스크롤도 안 되고 클릭도 안 되고 뭐 아무것도 안 된다면? +

    +

    브라우저가 항상 동기적으로만 동작한다면, 매우매우 불편할 것

    +

    + 당연히 웹뿐 아니라 안드로이드, iOS도 비동기적으로 동작할 수 + 있습니다 +

    + +
+ ), + }, + { + title: '보통 비동기를 어떻게 구현하냐', + content: ( +
+

아래는 C언어 예시

+ +

하지만 Process나 Thread 는 어렵습니다.

+
+ ), + }, + { + title: 'JavaScript 는 비동기를 쉽게 처리할 수 있는 언어', + content: ( +
+

+ 솔직히 JavaScript 진짜 이상하지만 비동기쪽은 정말 잘 만들어져 + 있습니다 +

+ {`, + ` console.log("비동기 작업 완료!");`, + `}, 2000); // 2초 후에 실행`, + ]} + /> + response.json())`, + ` .then(data => {`, + ` console.log('Data:', data);`, + ` })`, + ]} + /> + +
+ ), + }, + { + title: '싱글 스레드', + content: ( +
+

+ JavaScript 에는 스레드 개념이 없습니다 (프로세스는 당연히 더욱 + 없습니다) +

+

JavaScript 의 비동기는 이벤트 루프를 기반으로 동작합니다

+

코드를 먼저 보고, 그 다음에 원리를 이해해 보겠습니다

+
+ ), + }, + { + title: '가장 간단한 예시: setTimeout', + content: ( + console.log('2')`, + ``, + `setTimeout(callback, 1000);`, + ``, + `console.log('3');`, + ]} + /> + } + description={[ + '콜백 패턴을 사용하는 대표적인 비동기 코드', + '1 -> 3 -> 2 순서로 출력된다', + <> + 을 수행하면, 브라우저가 delay + 후에 콜백을 수행해준다 + , + + JavaScript가 싱글스레드인거지, 브라우저는 스레드 많습니다 + , + ]} + /> + ), + }, + { + title: '콜백 패턴?', + content: ( + + {`, + ` console.log('비동기 작업 완료!');`, + `}, 2000);`, + ]} + /> + setCount(count + 1)} />`, + ``, + `// 이것도 콜백`, + `document.addEventListener('keydown', (event) => {`, + ` console.log('키 눌림:', event.key);`, + `});`, + ]} + /> +
+ } + description={[ + '함수의 인자로 함수를 넘겨서, "적절한 시점에 이거 호출해줘" 라고 요청하는 패턴', + '그래서 콜백', + ]} + /> + ), + }, + { + title: '콜백 패턴의 단점 (1) 콜백 지옥', + content: ( + {`, + ` foo();`, + ` setTimeout(() => {`, + ` boo();`, + ` setTimeout(() => {`, + ` bar();`, + ` }, 1000);`, + ` }, 1000);`, + `}, 1000);`, + ]} + /> + } + description={['호출이 깊어지면 깊어질수록 가독성이 망가짐']} + /> + ), + }, + { + title: '콜백 패턴의 단점 (2) 에러 처리', + content: ( + {`, + ` try {`, + ` foo()`, + ` setTimeout(() => {`, + ` try {`, + ` boo();`, + ` setTimeout(() => {`, + ` try {`, + ` bar();`, + ` } catch (error) {`, + ` console.error('Error in third setTimeout:', error);`, + ` }`, + ` }, 1000);`, + ` } catch (error) {`, + ` console.error('Error in second setTimeout:', error);`, + ` }`, + ` }, 1000);`, + ` } catch (error) {`, + ` console.error('Error in first setTimeout:', error);`, + ` }`, + `}, 1000);`, + ]} + /> + } + description={[ + '앞의 문제에 이어서, 여기에다가 에러 처리까지 해주려면 더 끔찍해진다', + ]} + /> + ), + }, + { + title: '콜백 패턴의 단점 (3) 신뢰의 문제', + content: ( + {`, + ` 카드에서돈빼가기(번호);`, + ` },`, + `});`, + ]} + /> + } + description={[ + '콜백의 실행 권한은 개발자가 아닌 호출자에게 있다', + '카드 번호 입력 라이브러리를 만든 사람이 버그를 만들었다면 어떻게 될까?', + '유저는 결제를 한 번 했는데 돈이 5번 빠져나간다면?', + '억지스럽다고 느껴질 수 있지만 충분히 가능한 시나리오고, 좀더 나은 방법이 있다', + ]} + /> + ), + }, + { + title: 'Promise', + content: ( + {`, + ` 카드에서돈빼가기();`, + ` });`, + ]} + /> + } + description={[ + '좀더 발전된 비동기 패턴. 대부분의 비동기 처리는 Promise 로 합니다', + <> + , ,{' '} + 를 사용해서 콜백 지옥을 해결 + , + '콜백의 실행 권한이 개발자도 호출자도 아닌 브라우저에게 있으므로 신뢰할 수 있음', + '', + 'Pending, Fulfilled, Rejected 세 가지 상태를 가지는 특수한 객체', + '처음에는 Pending', + 'Fullfilled 상태가 되면 then() 으로 전달받은 콜백을 수행', + 'Rejected 상태가 되면 catch() 로 전달받은 콜백을 수행', + ]} + /> + ), + }, + { + title: 'Promise 예시 코드: API 호출', + content: ( +
+ response.json())`, + ` .then((data) => window.alert(data.title))`, + ]} + /> + +
+ 는 http 요청을 한 다음 요청 결과를 + 담Promise 를 반환하는 함수 +
+ +

+ 이 점이 중요합니다. "담은" 아니고 + "담을"입니다. +

+ +
), }, + { + title: 'async 와 await', + content: ( +
+
+ 그러면 이 최선이냐? +
+
+ 물론 좋지만, 조금 더 동기적인 코드처럼 보이는 문법이 있음 +
+ {`, + ` fetch('https://jsonplaceholder.typicode.com/todos/1')`, + ` .then((response) => response.json())`, + ` .then((data) => window.alert(data.title))`, + ` .catch(() => console.error('에러 발생'));`, + `}`, + ]} + /> + {`, + ` try {`, + ` const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');`, + ` const data = await response.json();`, + ` window.alert(data.title);`, + ` } catch (error) {`, + ` console.error('Error:', error);`, + ` }`, + `}`, + ]} + /> +
async function 에서는 await 이라는 문법을 쓸 수 있다
+
+ 이 경우 then 콜백의 파라미터로 넘어올 게 함수 반환값처럼 + 내려오고 +
+
catch 콜백의 파라미터로 넘어올 게 throw 된 에러
+
+ 좀더 동기적인 코드처럼 보이게 해 줘서 읽기 편하게 만드는 + syntatic sugar입니다 +
+
+ ), + }, + { + title: 'JavaScript는 어떻게 싱글 스레드로 비동기를 처리할까?', + content:
TBD
, + }, ]} /> ), diff --git a/frontend/lecture/src/pages.tsx b/frontend/lecture/src/pages.tsx index 1c1dc53..74e8890 100644 --- a/frontend/lecture/src/pages.tsx +++ b/frontend/lecture/src/pages.tsx @@ -6,6 +6,7 @@ import { makeGameAssignment } from '@/assignments/MakeGame/assignment'; import { profilePageAssignment } from '@/assignments/ProfilePage'; import { tutorialAssignment } from '@/assignments/Tutorial'; import { ExternalLink } from '@/components/ExternalLink'; +import { apiCallLecture } from '@/lectures/ApiCall/lecture'; import { asyncLecture } from '@/lectures/Async/lecture'; import { environmentLecture } from '@/lectures/Environment'; import { initializeProjectLecture } from '@/lectures/InitializeProject'; @@ -41,6 +42,7 @@ export const pages: ( { path: '/react-basic', ...reactBasicLecture }, { path: '/react-apis', ...reactApisLecture }, { path: '/async', ...asyncLecture }, + { path: '/api-call', ...apiCallLecture }, { type: 'lecture', title: 'TypeScript',