본문 바로가기
Programming Languge/JavaScript

[Codeit;] 자바스크립트 웹 개발 기본기

by 양진주 2024. 8. 3.

1. 웹 기초 다지기 

//fetch: 리퀘스트 전송, 리스폰스 수신 함수
fetch('https://www.google.com')
	//리스폰스 수신 시 실행(콜백 함수)
    .then((response) => respones.text())
    .then((result) => { console.log(result); });

 

2. Web API 배우기 

fetch('https://jsonplaceholder.typicode.com/users')
   .then((response) => response.text())
   .then((result) => {
    	const users = JSON.parse(result);
        //JSON.parse: string 타입 JSON 데이터 -> 객체 타입 변환 
}

 

요청(requese)

= Head(Request 부가 정보 - 메소드) + Body(실제 데이터)

 

- 데이터 조회: GET Request - READ

- 데이터 추가: POST Request - CREATE

- 데이터 수정: PUT Request - UPDATE

- 데이터 삭제: DELTE Request - DELETE

 

fetch('https://learn.codeit.kr/api/members',{
	method: 'POST', //GET 이외의 method 명시 필수 
    //기본 method: GET
	body: JSON.stringify(newMember), // js 객체 -> string 타입
})
	.then((response) => response.text())
	.then((result) => { console.log(result); });

 

const member = {
	name: 'Alice',
    email: 'alice@codeitmall.kr',
    department: 'marketing',
}

fetch('https://learn.codeit.kr/api/members/2',{
	method: 'PUT',
	body: JSON.stringify(member),
    //JS 객체 데이터 외부 전송: string 타입 변환 필요 
})
	.then((response) => response.text())
	.then((result) => { console.log(result); });
fetch('https://learn.codeit.kr/api/members/2',{
	method: 'DELETE',
    //바디 프로퍼티 불필요 
})
	.then((response) => response.text())
	.then((result) => { console.log(result); });

 

REST API: Web API 설계를 할 때, 준수하기 위해 노력하는 일종의 가이드라인

REST architecture: 웹이 갖추어야 할 이상적인 구조

  1. Client-Server: 양측의 관심사를 분리
  2. Stateless: Server는 Client가 보낸 각 리퀘스트의 맥락(context) 저장 X, 매 리퀘스트 각각 독립적인 것으로 취급
  3. Cache: 네트워크 비용을 절감
  4. Uniform Interface
    1. identification of resources: 리소스 - URI로 식별
    2. manipulation of resources through representations: 동일한 리소스라도 여러 개의 표현 가능 
    3. self-descriptive messages: Client의 리퀘스트와 Server의 리스폰스 모두 그 자체에 있는 정보만으로 모든 것을 해석
    4. hypermedia as the engine of application state: Server의 리스폰스에는 현재 상태에서 다른 상태로 이전할 수 있는 링크를 포함
  5. Layered System: Client와 Server 사이에는 프록시(proxy), 게이트웨이(gateway)와 같은 중간 매개 요소
  6. Code on Demand(Optional): Client는 받아서 바로 실행할 수 있는 applet이나 script 파일을 Server로부터 받을 수 있어야

응답(response)

= Head(Response 부가 정보 - 상태 코드, Content-Type) + Body(실제 데이터)

상태 코드 

200: 요청 내용을 서버가 정상 처리

404: 해당 URL에 해당하는 데이터를 찾을 수 없음

Content-Type ➡️ 바디의 데이터 추론 가능 

= 주 타입/서브 타입 

 

3. 비동기 실행과 Promise 객체 

비동기 실행: 특정 작업을 시작하고 완벽하게 다 처리하기 전에 다음 코드로 흐름이 넘어감, 나중에 콜백 실행 

➡️ 동일한 작업을 더 빠른 시간 내에 처리 

//비동기 함수 종류

//원하는 시간만큼 뒤로 미루기
setTimeout(() => {console.log('b'); }, 2000);

//특정 콜백을 일정한 시간 간격으로 실행
setInterval(() => {console.log('b'); }, 2000);

//이벤트 핸들러
btn.addEventListener('click', function(e) {
	console.log("hello");
});

//fetch
fetch('https://www.google.com')
	.then((response) => response.text())
    .then((result) => {console.log(result); });

 

promise 객체: 작업에 관한 '상태 정보'를 갖고 있는 객체 

- pending

- fulfilled ➡️ 작업 성공 결과 가짐 

- rejected ➡️ 작업 실패 정보 가짐 

 

promise.then
//프로미스 객체가 fulfilled 상태가 되면 실행할 콜백 등록
//새로운 promise 객체 리턴

 

fetch('https://jsonplaceholder.typicode.com/users')
    .then((response) => response.text(), (error) => { console.log(error); })
    // 프로미스 객체 fulfilled 상태일 때 실행, rejected 상태일 때 실행 
    .then((result) => { console.log(result); });
    // fulfilled: 작업 성공 이유 출력, rejected: 작업 실패 이유 출력

 

then 메소드

 

i) 실행된 콜백이 어떤 값을 리턴하는 경우

//Promise 객체
fetch('https://jsonplaceholder.typicode.com/users')
  .then((response) => response.json()) //Promise 객체 리턴(json, text...)
  .then((result) => { console.log(result) });
  //콜백에서 리턴하는 Promise 객체 -> then 메소드가 그대로 리턴
//Promise 객체 X(숫자, 문자열, 일반 객체)

fetch('https://jsonplaceholder.typicode.com/users') //rejected
  .then((response) => response.json(), (error) => 'Try again!') //fulfilled, 작업 실패 결과: 'Try again!' 리턴
  .then((result) => { console.log(result) }); //fulfilled, 작업 실패 결과: 'Try again!' 리턴

 

ii) 실행된 콜백이 아무 값도 리턴하지 않는 경우 

fetch('https://jsonplaceholder.typicode.com/users') //rejected
  .then((response) => response.json(), (error) => { alert('Try again!'); }) //alert('Try again!') 실행, 리턴값 X -> undefined 리턴 
  .then((result) => { console.log(result) }); //fulfilled, 작업 성공 결과: undefined

 

iii) 실행된 콜백 내부에서 에러 발생

//정의하지 않은 함수 콜백 사용
//인위적으로 throw문 사용 

const promise = fetch('https://jsonplaceholder.typicode.com/users')
  .then((response) => { throw new Error('test'); }); //rejected, 작업 실패 정보: 해당 Error 객체

 

iv) 아무런 콜백도 실행되지 않을 때 

fetch('https://www.google.com') //rejected
  .then((response) => response.text()) //두 번째 콜백 X -> 콜백 실행 X -> 이전 Promise 객체와 동일한 상태 & 결과
  .then((result) => { console.log(result) }, (error) => { alert(error) });

 

fetch('https://jsonplaceholder.typicode.com/users')
    .then((response) => response.text())
    .catch((error) => { console.log(error); })
    //.catch: Promise 객체 rejected일 때 실행할 콜백 등록 
    .then((result) => { console.log(result); });
    .finally(() => { console.log(error); });
    //.finally: Promise 객체 상태 상관 없이 항상 실행, 파라미터 불필요

 

//Promise 생성(비동기 실행 함수 사용 코드 -> Promise 기반의 코드)
const p = new Promise((resolve, reject) => {
	//Promise 객체가 생성될 때 자동으로 실행되는 함수(executor 함수)
    setTimeout(() => { resolve('success'); }, 2000);
    //객체 p - fulfilled, 작업 성공 결과: 'success'
    setTimeout(() => { reject(new Error('fail')); }, 2000);
    //객체 p - rejected, 작업 실패 결과: new Error('fail')
});

 

+) 다른 Promise 메소드들 

//then 메소드

const p1 = fetch('https://learn.codeit.kr/api/members/1').then((res) => res.json());
const p2 = fetch('https://learn.codeit.kr/api/members/2').then((res) => res.json());
const p3 = fetch('https://learn.codeit.kr/api/members/3').then((res) => res.json());

Promise
  .all([p1, p2, p3]) //아규먼트로 들어온 모든 Promise 객체 fulfilled 상태가 될 때까지 대기
  //fulfilled, 작업 성공 결과: 각 Promise 객체의 작업 성공 결과들로 이루어진 배열
  .then((results) => {
    console.log(results); // Array : [1번 직원 정보, 2번 직원 정보, 3번 직원 정보]
  .catch((error) => {
    console.log(error);  
  });
//race 메소드 

const p1 = new Promise((resolve, reject) => {
	setTimeout(() => resolve('Success'), 1000);
}));
const p2 = new Promise((resolve, reject) => {
	setTimeout(() => reject(new Error('fail')), 2000);
}));
const p3 = new Promise((resolve, reject) => {
	setTimeout(() => reject(new Error('fail2')), 4000);
}));

Promise 
	.race([p1, p2, p3]) //가장 빨리 상태가 결정된 Promise 객체 선택
    .then((result) => {
    	console.log(result);
    })
    .catch((value) => {
    	console.log(value);
    });

 

//allSettled 메소드
//배열 속 객체들이 모두 fulfilled || rejected 되면 
//fulfilled, 작업 성공 결과: Promise 객체

[
   {status: "fulfilled", value: 1},
   {status: "fulfilled", value: 2},
   {status: "fulfilled", value: 3},
   {status: "rejected",  reason: Error: an error}
]
//any 메소드
//가장 먼저 fulfilled 된 Promise 객체의 상태 & 결과 
/*
만약 모든 객체 rejected
rejected, 작업 실패 정보: AggregateError
*/

 

 

4. async/await을 활용한 세련된 비동기 코드 

//async: 함수 안에 비동기 실행 부분 있음 표시, Promise 객체 리턴  
async function fetchAndPrint() {
	try {
		const response = awit fetch('https://jsonplaceholder.typicode.com/users');
        const result = await response.text();
        /*
        await: 해당 프로미스 객체 fulfilled || rejected 될 때까지 대기, async 안에서만 사용 가능 
        Promise 객체 fulfilled -> 작업 성공 결과 리턴
        */
        console.log(result);
        
	} catch (error) {
    	console.log(error);
        //Promise 객체 rejected -> 작업 성공 결과 리턴
        
    } finally {
    	conosle.log('exit');
    }
}

fetchAndPrint();

 

asynce function fetchAndPrint() {
	return 3;
}

fetchAndPrint();

//fulfilled, 작업 성공 결과: 3 리턴

 

i) 어떤 값을 리턴하는 경우

//Promise 객체
async function fetchAndPrint() {
	return new Promise((resolve, reject) => {
    	setTimeout(() => { resolve('abc'); }, 4000);
    });
}

fetchAndPrint();
//해당 Promise 객체 리턴

 

//Promise 객체X(숫자, 문자열, 일반 객체)
async function fetchAndPrint() {
	return 3;
}

fetchAndPrint();
//fulfilled, 작업 성공 결과: 리턴 값

 

ii) 실행된 콜백이 아무 값도 리턴하지 않는 경우 

async function fetchAndPrint() {
	console.log('Hello Programming!');
}

fetchAndPrint();
//fulfilled, 작업 성공 결과: undefined


iii) 실행된 콜백 내부에서 에러 발생

async function fetchAndPrint() {
	throw new Error('Fail');
}

fetchAndPrint();
//rejected, 작업 실패 결과: 에러 객체

 

//async 함수 표현

//함수 선언식
async function example(a, b) {
	return a + b;
}

//함수 표현식(이름 있음)
const example2_1 = async function add(a, b) {
	return a + b;
};

//함수 표현식(이름 없음)
const example2_2 = async function(a, b) {
	return a + b;
}

//화살표 함수
const example3_1 = async function (a, b) => a + b;

//즉시 실행 함수
(async function print(sentence) {
	console.log(sentence);
    return sentence;
} ('I love JavaScript!');

(async function (a, b) {
	return a + b;
} (1, 2));

(async (a, b) => {
	return a + b;
}) (1, 2);

(async (a, b) => a + b)(1, 2);