이벤트 루프: 이벤트 발생 시 호출할 콜백 함수들을 관리하고, 호출 순서를 결정.
태스크 큐: 이벤트 발생 후 호출되어야 할 콜백함수들이 순서대로 기다리는 공간.
백그라운드: 타이머나 I/O 작업 콜백, Event Listener들이 대기하는 공간. 여러 작업 동시 실행 OK.
- 호출스택과 백그라운드가 동시에 실행되면 멀티 스레드(multi thread)
setTimout
, setInterval
, 네트워크 요청
, HDD의 파일을 읽는 명령어(fs)
, 암호화 명령어
, 압축명령어
... 요정도Ex)
Promise
의 then
이나 catch
부분은 setTimeout 이후 남아있는 익명 함수보다 우선순위가 더 높아서 'wow'보다 'hi'가 먼저 실행됨 ( process.nextTick
도 우선순위 높아서 새치기~)if (true) {
var x = 3;
}
console.log(x); // 3
if (true) {
const y = 3;
}
console.log(y); // Uncaught ReferenceError: y is not defined
const a = 0;
a = 1; // Uncaught TypeError: Assignment to constant variable.
let b = 0;
b = 1; // 1
const c; // Uncaught SyntaxError: Missing initializer in const declaration
var num1 = 1;
var num2 = 2;
var result = 3;
var string1 = num1 + ' 더하기 ' + num2 + '는 \'' + result + '\'';
console.log(string1); // 1 더하기 2는 '3'
🔽
const num3 = 1;
const num4 = 2;
const result2 = 3;
const string2 = `${num3} 더하기 ${num4}는 '${result2}'`;
console.log(string2); // 1 더하기 2는 '3'
function add1(x, y) {
return x + y;
}
const add2 = (x, y) => {
return x + y;
};
const add3 = (x, y) => x + y;
const add4 = (x, y) => (x + y);
function not1(x) {
return !x;
}
const not2 = x => !x;
add 1~4 모두 같은 의미의 함수임.
함수 본문이 return만 있는 경우 return 생략 가능
객체를 리턴하는 경우는 소괄호 필수!!
```jsx
const obj = (x,y) ⇒ ({x,y});
```
// <구소스>
var relationship1 = {
name: 'zero',
friends: ['nero', 'hero', 'xero'],
logFriends: function () {
var that = this;
// relationship1을 가리키는 this를 that에 저장
this.friends.forEach(function (friend) {
console.log(that.name, friend);
});
},
};
relationship1.logFriends();
this
를 가지기 때문에 부모의 this를 다른 함수에서 사용하려면 that
같은 변수에 넣어주고 사용 해야함// <현소스>
const relationship2 = {
name: 'zero',
friends: ['nero', 'hero', 'xero'],
logFriends() {
this.friends.forEach(friend => {
console.log(this.name, friend);
});
},
};
relationship2.logFriends();
this
와 this.name의 this
는 같음this를 쓸 거면 function을 쓰고, this 필요 없으면 화살표 함수 쓰는 것을 권장
candyMachine
부터 시작해서 속성을 찾아 들어 가야 함 😣// 구소스
var candyMachine = {
status: {
name: 'node',
count: 5,
},
getCandy: function () {
this.status.count--;
return this.status.count;
},
};
var getCandy = candyMachine.getCandy;
var count = candyMachine.status.count;
// 현소스
const candyMachine = {
status: {
name: 'node',
count: 5,
},
getCandy() {
this.status.count--;
return this.status.count;
},
};
const { getCandy, status: { count } } = candyMachine;
변수
} = 객체
; 로 객체 안의 속성을 변수 명으로 사용 가능 😁getCandy()
를 실행했을 때 결과가 canbyMachine.getCandy()
와 는 달라지므로 주의count
처럼 속성 안의 속성도 변수 명으로 사용 가능[예시]
// 속성 이름을 변수로 만들어줌
const example = {a:123, b:{c:135, d:146}}
const a = example.a;
const d = example.b.d;
// 차라리 이렇게 해라!
const{a,b:{d}} = example; // ※객체는 key가 일치해야함
console.log(a); //123
console.log(d); //146
배열도 구조 분해 할당 가능
// 구소스
var array = ['nodejs', {}, 10, true];
var node = array[0];
var obj = array[1];
var bool = array[3];
// 현소스
const array = ['nodejs', {}, 10, true];
const [node, obj, , bool] = array;
변수
] = 배열
; 형식//배열의 경우
arr= [1,2,3,4,5];
const x= arr[0];
const y= arr[1];
const z= arr[4];
//차라리 이렇게 해라!
const [x,y, , ,z]=arr; // ※배열은 자리가 똑같아야 함!
클래스는 사실 프로토타입
var Human = function(type) {
this.type = type || 'human';
};
Human.isHuman = function(human) {
return human instanceof Human;
}
Human.prototype.breathe = function() {
alert('h-a-a-a-m');
};
var Zero = function(type, firstName, lastName) {
Human.apply(this, arguments);
this.firstName = firstName;
this.lastName = lastName;
};
Zero.prototype = Object.create(Human.prototype);
Zero.prototype.constructor = Zero; // 상속하는 부분
Zero.prototype.sayName = function() {
alert(this.firstName + ' ' + this.lastName);
};
var oldZero = new Zero('human', 'Zero', 'Cho');
Human.isHuman(oldZero); // true
class Human {
constructor(type = 'human') {
this.type = type;
}
static isHuman(human) {
return human instanceof Human;
}
breathe() {
alert('h-a-a-a-m');
}
}
class Zero extends Human {
constructor(type, firstName, lastName) {
super(type);
this.firstName = firstName;
this.lastName = lastName;
}
sayName() {
super.breathe();
alert(`${this.firstName} ${this.lastName}`);
}
}
const newZero = new Zero('human', 'Zero', 'Cho');
Human.isHuman(newZero); // true
👁🗨 프로미스 꼭 알아두기!!
프로미스: 내용이 실행은 되었지만 결과를 아직 반환하지 않은 객체
const condition = true;
// true면 resolve, false면 reject
const promise = new Promise((resolve, reject) => {
if (condition) {
resolve('성공');
} else {
reject('실패');
}
});
// 다른 코드가 들어갈 수 있음
promise
.then((message) => {
console.log(message); // 성공(resolve)한 경우 실행
})
.catch((error) => {
console.error(error); // 실패(reject)한 경우 실행
})
.finally(() => { // 끝나고 무조건 실행
console.log('무조건');
});
then
을 붙이면 결과를 반환함
실행이 완료되지 않았으면 완료된 후에 then
내부 함수가 실행됨
resove
( 성공리턴값 ) → then
으로 연결
reject
(실패 리턴값) → catch
로 연결
finally
는 무조건 실행
promise
.then((message) => {
return new Promise((resolve, reject) => {
resolve(message);
});
})
.then((message2) => {
console.log(message2);
return new Promise((resolve, reject) => {
resolve(message2);
});
})
.then((message3) => {
console.log(message3);
})
.catch((error) => {
console.error(error);
});
then
연달아 사용 가능(프로미스 체이닝)then
안에서 return 한 값이 다음 then
으로 넘어감resolve
후 넘어감catch
로 이동catch
에서 한번에 처리const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');
Promise.all([promise1, promise2])
.then((result) => {
console.log(result); // ['성공1', '성공2'];
})
.catch((error) => {
console.error(error);
});
Promise.all( 배열 )
: 여러 개의 프로미스를 동시에 실행allSettled
로 실패한 것만 추려낼 수 있음Promise를 좀 더 간단하게 나타낸 것임
async function findAndSaveUser(Users) {
let user = await Users.findOne({});
user.name = 'zero';
user = await user.save();
user = await Users.findOne({ gender: 'm' });
// 생략
}
async
함수 안에서 await
를 사용할 수 있었는데, 요즘은 탑 레벨 await 로 나와서 그냥 사용 가능await
은 오른쪽 → 왼쪽 순으로 실행 (Promise then의 결과 값을 좌변에 저장 느낌~)async function main(){
try{
const result = await promise;
return result';
}catch(error){
console.log(error);
}
}
main().then((name)=> ... )
const name = await main();
async
함수에서 리턴 한 값은 main에서 무조건 then
으로 받아야 함const findAndSaveUser = async (Users) => {
try {
let user = await Users.findOne({});
user.name = 'zero';
user = await user.save();
user = await Users.findOne({ gender: 'm' });
// 생략
} catch (error) {
console.error(error);
}
};
async function findAndSaveUser(Users) {
// 생략
}
findAndSaveUser().then(() => { /* 생략 */ });
// 또는
async function other() {
const result = await findAndSaveUser();
}
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
// 여기에 예제 코드를 넣으세요.
</script>
GET 요청 보내기
- axios.get 함수의 인자로 요청을 보낼 주소 넣음
```jsx
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
axios.get('https://www.zerocho.com/api/get')
.then((result) => {
console.log(result);
console.log(result.data); // {}
})
.catch((error) => {
console.error(error);
});
</script>
```
- 프로미스 기반 코드라 async/await 사용 가능
```jsx
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
(async () => {
try {
const result = await axios.get('https://www.zerocho.com/api/get');
console.log(result);
console.log(result.data); // {}
} catch (error) {
console.error(error);
}
})();
</script>
```
POST 요청하는 코드 (데이터를 담아 서버로 보내는 경우)
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
(async () => {
try {
const result = await axios.post('https://www.zerocho.com/api/post/json', {
name: 'zerocho',
birth: 1994,
});
console.log(result);
console.log(result.data);
} catch (error) {
console.error(error);
}
})();
</script>
<script>
const formData = new FormData();
formData.append('name', 'zerocho');
formData.append('item', 'orange');
formData.append('item', 'melon');
formData.has('item'); // true
formData.has('money'); // false;
formData.get('item');// orange
formData.getAll('item'); // ['orange', 'melon'];
formData.append('test', ['hi', 'zero']);
formData.get('test'); // hi, zero
formData.delete('test');
formData.get('test'); // null
formData.set('item', 'apple');
formData.getAll('item'); // ['apple'];
</script>
append로 데이터를 하나 씩 추가
has 로 데이터 존재 여부 확인
get으로 데이터 조회
getAll로 데이터 모두 조회
delete로 데이터 삭제
set으로 데이터 수정
FormData POST 요청으로 보내기
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
(async () => {
try {
const formData = new FormData();
formData.append('name', 'zerocho');
formData.append('birth', 1994);
const result = await axios.post('https://www.zerocho.com/api/post/formdata', formData);
console.log(result);
console.log(result.data);
} catch (error) {
console.error(error);
}
})();
</script>
encodeURIComponent
로 한글 감싸서 처리 (URL아니고 URI )url : 서버에 있는 파일 위치
uri : 서버에 있는 자원의 위치 (요즘 이걸 더 많이 씀)
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
(async () => {
try {
const result = await axios.get(`https://www.zerocho.com/api/search/${encodeURIComponent('노드')}`);
console.log(result);
console.log(result.data); // {}
} catch (error) {
console.error(error);
}
})();
</script>
data-속성명
태그.dataset.속성명
으로 접근 가능<ul>
<li data-id="1" data-user-job="programmer">Zero</li>
<li data-id="2" data-user-job="designer">Nero</li>
<li data-id="3" data-user-job="programmer">Hero</li>
<li data-id="4" data-user-job="ceo">Kero</li>
</ul>
<script>
console.log(document.querySelector('li').dataset);
// { id: '1', userJob: 'programmer' }
</script>
인프런 Node.js 강의
Zerocho 님의 "Node.js 교과서 - 기본부터 프로젝트 실습까지" 강의를 기반으로 작성한 문서입니다.