비구조화 할당(destructuring)
리액트를 공부했을 때 항상 상단에 import React, { Component } from 'react';
를 썼었는데, 저 { Component }
의 의미를 몰랐었다.
근데 이게 비구조화 할당이었다! 비구조화 할당이 뭔지 정리해보자.
const object = {
status : {
name: 'node',
count: 4,
},
getCount(){
this.status.count--;
return this.status.count;
}
}
const {status, getCount} = object //object 객체의 각 속성이 status와 getCount에 할당된다. 반드시 객체의 속성 값과 변수 이름이 같아야한다.
console.log(status.name) //node
node에서도 의미를 모르고 썼던 const { Router } = require('express')
도 require('express')
로 가져온 객체에서 Router
의 속성을 변수로 꺼내온다는 의미이다.
위 예제에서 조심해야할 부분이 있다.
const object = {
status : {
name: 'node',
count: 4,
},
getCount(){
this.status.count--;
return this.status.count;
}
}
const {status, getCount} = object
getCount() //결과 : 객체 this를 못찾아서 아무일도 일어나지 않는다. 즉 count 값이 바뀌지 않는다.
getCount.call(object) //이렇게 객체를 연결해줘야 count가 3이 된다.
비구조화 할당은 배열도 된다!
const array = [1, {}, true, 'node']
const {number, obj, bool, name} = array; //배열의 순서에 맞게 변수로 꺼내올 수 있다...왕신기
콜백 지옥
Users.findOne('sy', (err,user)=>{
if(err){
console.error(err)
}
console.log(user)
Users.update('ha',(err,updatedUser)=>{
if(err){
console.error(err)
}
console.log(updatedUser)
Users.remove('ho',(err,removedUser) =>{
if(err){
console.error(err)
}
console.log(removedUser)
Users.callbackHell('hell',(err,hell)=>{
.....//콜백지옥
})
})
})
})
위 코드를 이해할 수 없다..like 사중포문과 같은 가독성..
그래서 나온게 Promise!
Promise
Promise는 결과값을 가지고 있지만 .then()
이나 .catch()
를 붙이기 전까지 반환하지 않는 것!
(결과를 lazy하게 뒤로 미룬다는 점에서 함수형 프로그래밍과 비슷하다고 개인적으로 생각한다…)
위의 코드를 대충 이렇게 바꿀 수 있다.
const Users = {
findOne(){
return new Promise((resolve,reject) => {
if(사용자를 찾았으면){
resolve(사용자) //인수로 넘긴 값(=사용자)이 then의 파라미터로 들어간다.
}else{
reject(못찾음)//인수로 넘긴 값이 catch의 파라미터로 들어간다.
}
})
},
update(){
return new Promise((resolve,reject) => {
if(업데이트 성공했으면){
resolve(사용자)
}else{
reject(실패)
}
})
},
remove(){
return new Promise(...)
},
}
Users.findOne('sy')
.then((user)=>{
console.log(user)
return Users.update('ha')//promise리턴
})
.then((updatedUser)=>{
console.log(updatedUser)
return Users.remove('ho')
})
.then((removedUser)=>{
console.log(removedUser)
})
.catch((err)=>{
console.error(err)
})
중요한 건 Promise의 왼쪽 파라미터 함수(예제에서는 resolve
)의 인자로 넘긴 값이 .then()
의 파라미터로 들어가고, Promise의 오른쪽 파라미터 함수(예제에서는 reject
)의 인자로 넘긴 값이 .catch()
의 파라미터로 들어간다는 것이다.
.then()
에 리턴값 Promise가 있으면 다음 .then()
으로 넘어간다.
async / await
어쨌든 Promise를 써도 아래 코드는 비동기적으로 실행된다.
Users.findOne('sy')
.then((user)=>{
console.log(user)
return Users.update('ha')//promise리턴
})
.then((updatedUser)=>{
console.log(updatedUser)
return Users.remove('ho')
})
.then((removedUser)=>{
console.log(removedUser)
})
.catch((err)=>{
console.error(err)
})
console.log('콘솔에 내가 먼저 찍힌다.')
그럼 코드 순서와 실행 순서가 같아지는 동기식으로 어떻게 바꿀까?
async / await 키워드를 사용한다!
async func() = {
try{
const user = await Users.findUser('sy') //Promise의 resolve() 또는 reject()의 파라미터로 넘기는 값이 user로 리턴된다.
console.log(user)
const updated = await Users.update('ha')
console.log(updated)
const removed = await Users.remove('ho')
console.log(removed)
console.log('난 맨 마지막에 찍힌다.')
} catch(err){
console.error(err)
}
}
func()
위의 코드처럼 함수 앞에는 async
, Promise에는 await
을 붙여주면 코드를 작성한 순서대로 기다렸다가 다음 코드가 실행된다. = 동기식
다시 찾아볼 부분
.bind()
의 뜻
Comments