1. JSON
JSON (JavaScript Object Notation)은 데이터 교환을 위한 간단하고 경량의 텍스트 기반 구조다. JSON은 읽기 쉬운 key-value 쌍 형식을 사용하여 데이터를 표현한다. 그 주요 특징은 다음과 같다.
1) JavaScript Object Notation (자바스크립트 객체 표기법): JSON은 원래 JavaScript 언어의 객체 표기법을 기반으로 하여 개발되었다.
2) 간단한 데이터 교환 형식: JSON은 서버와 클라이언트 간 또는 시스템 간의 데이터 전송을 위해 사용되며, 그 구조가 간단하고 명확하여 데이터 교환을 쉽게 할 수 있다.
3) 경량 텍스트 기반의 구조: JSON은 텍스트 기반으로, 이는 대부분의 프로그래밍 언어에서 쉽게 읽고 쓸 수 있다는 것을 의미다. 이로 인해 데이터를 교환하는 데 있어 효율적이다.
4) 읽기 쉬운 key : value 형식: 데이터는 key와 value의 쌍으로 구성되며, 이 형식은 사람이 읽고 이해하기 쉽다.
5) 특정 언어에 제한적이지 않고 독립적인 방식: JSON은 JavaScript에 국한되지 않고 다양한 프로그래밍 언어에서 사용할 수 있다. 이는 JSON이 프로그래밍 언어 독립적인 데이터 포맷이라는 것을 의미한다.
1-1. JSON 생성
1) Object ➔ JSON (stringify)
JSON.stringify() 메소드는 JavaScript 객체 (또는 값)를 JSON 문자열로 변환한다.
json = JSON.stringify(['apple', 'banana']);
console.log(json); // 출력: '["apple","banana"]'
문자열 배열 ['apple', 'banana']를 JSON 문자열 '["apple","banana"]'로 변환한다.
2) JSON ➔ Object (parse)
JSON.parse() 메소드는 JSON 문자열을 JavaScript 객체로 변환한다.
let json = JSON.stringify(['apple', 'banana']);
console.log(json); // 출력: '["apple","banana"]'
const obj = JSON.parse(json);
console.log(obj); // 출력: ['apple', 'banana']
먼저 배열 ['apple', 'banana']를 JSON 문자열로 변환한 후, 다시 이 JSON 문자열을 JavaScript 배열로 변환하여 출력한다.
3) JSON 생성 시 제외되는 타입:
JavaScript의 JSON.stringify() 함수는 객체를 JSON 문자열로 변환할 때 일부 타입을 자동으로 제외한다. 이 예시에서는 두 가지 타입이 제외된다.
- 함수 : JavaScript 함수는 JSON으로 변환되지 않습니다. 이 예시에서 jump 속성(함수)는 결과 JSON에 포함되지 않는다.
- 심볼(Symbol) : 심볼 또한 JSON으로 변환되지 않는다. symbol 속성은 결과 JSON에서 제외된다.
const rabbit = {
name: 'tori',
color: 'white',
size: null,
birthDate: new Date(),
jump: () => {
console.log(`${rabbit.name} can jump!`);
},
symbol: Symbol('id')
};
let json = JSON.stringify(rabbit);
console.log(json); // 출력: {"name":"tori","color":"white","size":null,"birthDate":"2024-01-22T12:00:00.000Z"}
birthDate는 Date 객체이며, 이는 JSON으로 변환될 때 문자열로 변환된다.
4) JSON 생성 시 사용할 속성 지정
JSON.stringify() 함수의 두 번째 인자로 속성 이름의 배열을 전달하여, JSON으로 변환하고자 하는 특정 속성을 지정할 수 있다.
let json = JSON.stringify(rabbit, ['name', 'color', 'size']);
console.log(json); // 출력: {"name":"tori","color":"white","size":null}
name, color, size 속성만이 JSON으로 변환된다. birthDate, jump, symbol 속성은 결과 JSON에 포함되지 않는다.
2. 비동기 처리
2-1. Callback
콜백 함수는 특정 작업(예: API 호출, 타이머 등)이 완료된 후에 실행되도록 설계된 함수다. 이런 함수는 다른 함수의 매개변수로 전달되어, 그 함수 내부에서 적절한 시점에 호출된다.
1) 기본 예시
console.log(1);
setTimeout(delayPrint, 1000);
console.log(3);
function delayPrint() {
console.log(2);
}
delayPrint 함수는 콜백 함수로서, setTimeout에 의해 1초 후에 호출된다. 따라서 출력은 1, 3, 그리고 1초 후에 2 순서로 이루어진다.
2) Callback 함수 예제
class UserStorage {
// loginUser 메소드는 ID와 비밀번호를 받아 로그인을 시도합니다.
loginUser(id, password, onSuccess, onError) {
// 비동기 작업(여기서는 setTimeout으로 모의 구현)
setTimeout(() => {
// 성공 조건을 확인합니다.
if ((id === 'java' && password === 'script') ||
(id === 'call' && password === 'back')) {
onSuccess(id); // 성공 시 onSuccess 콜백 호출
} else {
onError(new Error('not found')); // 실패 시 onError 콜백 호출
}
}, 2000);
}
// getRoles 메소드는 사용자 ID를 받아 권한을 확인합니다.
getRoles(id, onSuccess, onError) {
// 비동기 작업
setTimeout(() => {
// 사용자 ID에 따른 권한 할당
if (id === 'java') {
onSuccess({ id: 'java', role: 'admin' });
} else if(id === 'call') {
onSuccess({ id: 'call', role: 'manager' });
} else {
onError(new Error('no access')); // 권한 없음 에러 처리
}
}, 1000);
}
}
fetchUserData 함수는 비동기적으로 사용자 데이터를 가져오는 함수다. 실제 네트워크 요청을 모의하기 위해 setTimeout을 사용했다. 이 함수는 userId와 콜백 함수 callback을 매개변수로 받는다. 데이터가 준비되면 callback 함수가 호출되며, 이 때 displayUserName 함수가 callback으로 전달되어 사용자 이름을 콘솔에 출력한다.
2-2. Promise
Promise는 JavaScript에서 비동기 작업을 용이하게 처리하기 위해 도입된 객체다. 콜백 함수의 복잡성과 중첩 문제를 해결하는 데 도움이 되며, 코드의 가독성과 유지 보수성을 크게 향상시킨다.
2-2-1. Promise의 주요 개념
1) 비동기 작업을 위한 객체: Promise는 비동기 작업을 캡슐화하는 객체다. 비동기 작업의 결과(성공 또는 실패)를 나타낸다.
2) 콜백 함수의 대체: 전통적인 콜백 함수 대신 사용되며, 코드의 중첩을 줄여준다.
3) 성공과 실패 처리
- resolve: 비동기 작업이 성공적으로 완료되었을 때 호출됩니다. resolve 함수에 전달된 값은 Promise 사용자에게 전달된다.
- reject: 비동기 작업 중 에러가 발생했을 때 호출됩니다. reject 함수에 전달된 에러는 Promise 사용자에게 전달된다.
2-2-2. Promise의 상태(State)
1) Pending (수행중): 초기 상태, 성공 또는 실패가 아직 결정되지 않은 상태다.
2) Fulfilled (성공/완료): 작업이 성공적으로 완료되어 resolve가 호출된 상태다.
3) Rejected (실패/거부): 작업 중 에러가 발생하여 reject가 호출된 상태다.
2-2-3. 데이터 제공자(Producer)와 사용자(Consumer)
1) Producer: Promise를 생성하고, 비동기 작업을 수행한 후 결과(resolve 또는 reject)를 제공한다.
2) Consumer: Promise의 결과를 사용합니다. .then(), .catch(), .finally() 메소드를 통해 결과를 처리한다.
- Promise 기본 사용법
const myPromise = new Promise((resolve, reject) => {
// 비동기 작업을 수행하는 코드
const condition = /* 조건 */;
if (condition) {
resolve('성공'); // 작업 성공 시
} else {
reject('실패'); // 작업 실패 시
}
});
// Promise의 결과 사용
myPromise.then((result) => {
console.log(result); // 성공 시 처리
}).catch((error) => {
console.error(error); // 실패 시 처리
});
- Promise 사용 예시
class UserStorage {
// loginUser 메소드는 ID와 비밀번호를 받아 Promise를 반환합니다.
loginUser(id, password) {
return new Promise((resolve, reject) => {
// 비동기 작업
setTimeout(() => {
// 성공 조건을 확인합니다.
if ((id === 'java' && password === 'script') ||
(id === 'call' && password === 'back')) {
resolve(id); // 성공 시 resolve 호출
} else {
reject(new Error('not found')); // 실패 시 reject 호출
}
}, 1000);
});
}
// getRoles 메소드는 사용자 ID를 받아 권한을 확인하는 Promise를 반환합니다.
getRoles(id) {
return new Promise((resolve, reject) => {
// 비동기 작업
setTimeout(() => {
// 사용자 ID에 따른 권한 할당
if (id === 'java') {
resolve({ id: 'java', role: 'admin' });
} else if (id === 'call'){
resolve({ id: 'call', role: 'manager' });
} else {
reject(new Error('no access')); // 권한 없음 에러 처리
}
}, 1000);
});
}
}
2-3. 동기와 비동기
2-3-1. 동기적 수행 (Synchronous Execution)
1) 한번에 하나씩 순서대로 작업 처리: 동기적 수행에서는 한 작업이 완료되어야만 다음 작업으로 넘어간다. 즉, 작업은 순차적으로 진행된다.
2) 블로킹 방식: 현재 실행 중인 작업이 완료될 때까지 기다리기 때문에, 해당 작업이 끝나기 전까지 다른 작업을 시작할 수 없다. 이를 '블로킹(blocking)'이라고 한다.
3) 예시: 데이터베이스 쿼리를 수행하고 결과가 반환될 때까지 기다리는 경우, 파일을 읽고 읽기 작업이 완료될 때까지 다음 코드를 실행하지 않는 경우 등이 있다.
function syncFunction() {
console.log("작업 1 시작");
console.log("작업 1 완료");
console.log("작업 2 시작");
// 작업 2 수행 (가정)
console.log("작업 2 완료");
}
console.log("동기적 수행 시작");
syncFunction();
console.log("동기적 수행 완료");
2-3-2. 비동기적 수행 (Asynchronous Execution)
1) 선행 작업 완료를 기다리지 않고 다음 작업 수행: 비동기적 수행에서는 하나의 작업이 끝나기를 기다리지 않고 다음 작업을 바로 시작할 수 있다.
2) 논블로킹 방식: 현재 작업이 완료되지 않았더라도 다른 작업을 계속 진행할 수 있다. 이를 '논블로킹(non-blocking)'이라고 한다.
3) 예시: 웹페이지에서 서버에 데이터를 요청하고, 서버의 응답을 기다리는 동안 다른 스크립트를 실행하는 경우, 파일을 비동기적으로 읽으면서 동시에 다른 코드를 실행하는 경우 등이 있다.
function asyncFunction() {
console.log("비동기 작업 1 시작");
setTimeout(() => {
// 비동기 작업 1 수행 (가정)
console.log("비동기 작업 1 완료");
}, 2000); // 2초 후에 완료
console.log("비동기 작업 2 시작");
setTimeout(() => {
// 비동기 작업 2 수행 (가정)
console.log("비동기 작업 2 완료");
}, 1000); // 1초 후에 완료
}
console.log("비동기 수행 시작");
asyncFunction();
console.log("비동기 수행 중..."); // 비동기 작업들이 완료되기 전에 이 로그가 출력됩니다.
2-3-3. 동기와 비동기의 차이점
1) 응답성: 동기적 수행은 작업이 차례대로 진행되기 때문에, 한 작업이 많은 시간을 소요할 경우 전체 프로세스의 응답성이 저하될 수 있다. 반면, 비동기적 수행은 여러 작업이 동시에 진행될 수 있어 응답성이 좋다.
2) 자원 활용: 비동기적 수행은 시스템 자원을 보다 효율적으로 사용할 수 있다. 예를 들어, I/O 작업이 진행되는 동안 CPU는 다른 작업을 수행할 수 있다.
3) 복잡성: 비동기적 수행은 동기적 수행에 비해 프로그래밍 복잡성이 증가할 수 있다. 비동기 작업의 결과 처리를 위해 콜백 함수, 프로미스, async/await 등의 방법이 사용되며, 이들을 효과적으로 관리해야 한다.
'웹 서비스 개발(FB,BE,SERVER,DB) > Javascript' 카테고리의 다른 글
DOM API (0) | 2024.03.06 |
---|---|
3. 함수 (0) | 2024.03.06 |
2. 자료형(DataType) (1) | 2024.03.06 |
1. JavaScript (0) | 2024.03.04 |
댓글