자다 일어났더니 너무 어지러워 검색해보니 이석증 이란다. ㄷㄷ

다행히 자연적으로 치료되는 경우가 많다고 하니 경과를 지켜봐야겠다.

뇌쪽이 문제가 아니어야 할 텐데 ㅠㅠ

제발 건강 문제 때문에 혹은 체력 문제 때문에 막히고 싶지는 않다...

 

과제도 이미 끝내서 조금 여유롭게 공부를 했다.
책이 굉장히 제목에 맞게 교과서적인 느낌이었다. 친절하게 이해되기 쉽게 천천히 그리고 많은 예시를 들어 설명해 준다. 읽는 사람이 굉장히 초보라도 쉽게 읽히는 느낌이다. 

그리고
처음으로 E북으로 책을 사 봤는데 괜찮은거 같다.
공부하기에 오히려 더 만족감을 느꼈다. 예를들면 형광펜 기능이 있어서 책의 중요한 부분에 형광 표시를 하면 그 부분이 독서노트에 저렇게 담기고  메모로 내 마음대로 정리도 할 수 있다.
그리고 정말 좋은 것은! 저렇게 담긴 형광펜이나 메모를 더블클릭하면 해당 페이지로 바로 이동하기 때문에 아주 쉽게 찾아가서 상세한 것을 다시 볼 수도 있다.
당연히 하꼬인 나는 내돈내산 이라고 알고 계실 것이다. 마음에서 우러나오는 추천! 드린다. 개발 꿈나무 입장으로서 생각해도 편리하게 잘 만든 것 같다 ㅎㅎ;;


아쉬운건 그림이나 텍스트 복사가 안되어서 인용하기 쉽지 않다는 것이었다. ㅠ

 


Node의 기본 개념들을 배웠고 기본적인 함수 호출 원리를 배웠다.
완전 비전공자라서 스택이나 큐라는 단어도 생소해서 가져와 봤다.

큐와 스택

큐(QUEUE) : 주기억장치에서 연속적인 공간을 배정해 데이터를 Rear 포인터가 가르키는 방향에서 삽입해 Front 방향에서 삭제되는 알고리즘

- 큐의 사전적 의미는 줄을 서서 기다리는 것, 큐 자료 구조는 줄을 서서 기다리는 것처럼 먼저 온 사람 먼저 나간다.

- 먼저 온 사람이 먼저 나감을 선입선출의 FIFO(First in first out)로 표현한다.

- 아무것도 없는 큐에서 데이터를 삭제하면 Under Flow Error 발생 반대로 꽉 찬 큐에 삽입 시 Over Flow Error

큐 활용 예시 :

- 프린터 인쇄 대기열

- 은행 업무

- 콜센터 고객 대기시간

- 프로세스 관리

- 너비 우선 탐색

- 캐시

스택(Stack) : 주기억 장치에서 연속적인 공간을 배정해 1, 2, 3 같이 차례대로 삽입

- 사전적 의미는 쌓아 올리는 것. 스택 자료 구조는 책을 쌓는것처럼 차곡차곡 쌓아올린 형태의 자료구조다.

- 먼저 올린 책은 먼저 꺼낼 수 없다. 마지막에 올린 책부터 꺼내야 하며 아니면 무너질 것이다.

- 위를 마지막에 들어온게 먼저 나간다고 후입선출(LIFO, Last-in-First-Out) 구조라고 부른다.

- 아무것도 없는 스택에서 작업 수행 시 stack Under Flow Error 발생 꽉 찬 큐에 삽입 시 Stack Over Flow Error

스택 활용 예시 :

- 웹 브라우저 방문기록의 뒤로가기

- 역순 문자열

- 실행 취소

- 후위 표기법 계산

- 수식 괄호 검사 (연산자 우선순위 표현의 경우)

[출처] [Algorithm] 알고리즘 - 자료 구조, 선형 구조 (배열, 스택, 큐)|작성자 넬티아

프로세스와 스레드의 차이

프로세스 : 프로세스는 운영체제에서 할당하는 작업의 단위입니다. 노드나 웹 브라우저 같은 프로그램은 개별적인 프로세스입니다. 프로세스 간에는 메모리 등의 자원을 공유하지 않습니다.

스레드 : 스레드는 프로세스 내에서 실행되는 흐름의 단위입니다. 프로세스는 스레드를 여러 개 생성해 여러 작업을 동시에 처리할 수 있습니다. 스레드들은 부모 프로세스의 자원을 공유합니다. 같은 주소의 메모리에 접근 가능하므로 데이터를 공유할 수 있습니다.

 


Node는 싱글스레드를 사용하고 있다.
언뜻 보면 여러 개의 일을 동시에 처리할 수 있으므로 멀티 스레드가 싱글 스레드보다 좋아 보이지만 꼭 그런 것은 아니다. 예시를 들어보겠다. 한 음식점에 점원이 한 명 있다. 손님은 여러명이다. 점원 한 명이 주문을 받아 주방에 넘기고, 주방에서 요리가 나오면 손님에게 서빙을 한다. 그 후 다음 손님의 주문을 받는다. 이런 구조라면 다음 손님은 이전 손님의 요리가 나올 때까지 아무것도 못 하고 기다려야 한다. 이것이 바로 싱글 스레드, 블로킹 모델이다. 매우 비효율적이다.
 이번에는 점원이 한 손님의 주문을 받고, 주방에 주문 내역을 넘긴 뒤 다음 손님의 주문을 받는다. 요리가 끝나기까지 기다리는 대신, 주문이 들어왔다는 사실만 주방에 계속 알려주는 것이다. 주방에서 요리가 완료되면 완료된 순서대로 손님에게 서빙한다. 요리의 특성에 따라 완료되는 순서가 다를 수 있으므로, 주문이 들어온 순서와 서빙하는 순서는 일치하지 않을 수도 있다. 이것이 바로 노드가 채택하고 있는 싱글 스레드, 논 블로킹 모델이다.
  멀티 스레드 방식에서는 손님 한 명이 올 때마다 점우너도 한 명씩 붙어 주문을 받고 서빙한다. 언뜻 보면 싱글 스레드보다 좋은 방법인 것 같지만, 장단점이 있다. 일단 손님 한 명당 점원도 한 명이면 서빙 자체는 걱정이 없다. 점우너 한 명에게 문제가 생겨도 다른 점원으로 대체하면 되기 때문이다. 하지만 손님의 수가 늘어날 수록 점원의 수도 늘어난다. 손님 수가 줄어들었을 대 일을 하지 않고 노는 점원이 있다는 것도 문제가 된다. 점원을 새로 고용하거나 기존 점원을 해고하는 데는 비용이 발생하기 때문이다. 

서버로 사용할때의 노드 특징 장 단점

특장점
노드는 개수는 많지만 크기는 작은 데이터를 실시간으로 주고 받는 데에 적합하다. 네트워크나 데이터베이스, 디스크 작업 같은 I/O에 특화되어 있기 때문이다. 실시간 채팅 어플리케이션이나 주식 차트, JSON 데이터를 제공하는 API 서버가 노드를 많이 사용한다.

구현이 편리하다.  왜냐하면 노드는 내장된 웹 서버를 사용하여 사용하면 되므로 편리하다. 하지만 나중에 서버 규모가 커지면 결국 nginx 등의 웹 서버를 노드 서버와 연결해야한다.

자바스크립트를 사용하므로 비교적 쉬우면서 개발 생산성을 획기적으로 높일 수 있다.

요즘은 XML 대신 JSON을 사용해서 데이터를 주고 받는데, JSON이 자바스크립트 형식이므로 노드에서는 쉽게 처리할 수 있다.


단점
기본적으로 싱글 스레드라서 CPU코어를 하나만 사용한다.

CPU 작업이 많은 서버로는 부적합하다.

노드 12 버전에서 워커 스레드 기능의 안정화로 멀티 스레드 작업을 할 수 있게 되었지만, 멀티 스레드 프로그래밍을 하는 것은 싱글 스레드에 비해 어렵다. 그리고 멀티스레드 프로그래밍을 하더라도 C, C++, Rust, Go와 같은 언어에 비해 속도가 많이 느리다.

싱글 스레드 방식으로 서버를 운영하기 때문에 하나뿐인 스레드가 에러로 인해 멈추면 서버 전체가 멈출 수 있다.

 

안정성과 보안성 측면의 문제도 이미 충분히 검증되었다. 규모가 큰 곳을 꼽자면 미국항공우주국(NASA), 에어비앤비, 우버, 넷플릭스, 링크드인 등에서 노드를 사용하고 있습니다. 페이팔, 월마트, 이베이와 같이 결제 시스템을 사용하는 대기업들도 노드로 서비스를 운영한다. 국내에서도 네이버, 카카오, 위메프, 야놀자 같은 기업들이 노드를 사용하고 있다.

출처 Node.js 교과서 개정2판 
조현영 저

돌아온 알고리즘 시간!

N개의 문자열이 입력되면 그 중 가장 긴 문자열을 출력하는 프로그램을 작성하세요.
▣ 입력설명
첫 줄에 자연수 N이 주어진다.(3<=N<=30)
두 번째 줄부터 N개의 문자열이 주어진다. 문자열의 길이는 100을 넘지 않습니다.
각 문자열의 길이는 서로 다릅니다.
▣ 출력설명
첫 줄에 가장 긴 문자열을 출력한다.
▣ 입력예제 1
5
teacher
time
student
beautiful
good
▣ 출력예제 1
beautiful

풀이
for문 돌려서 하나하나 불러오면서 배열 길이값으로 최대값 찾기 하면 된다

function solution(s){
    let answer, max = Number.MIN_SAFE_INTEGER;
    for(let x of s) {
        if(x.length > max) {
            max = x.length;
            answer=x;
        }
    }
    return answer
    
}
let str=["teacher", "time", "student","beautiful","good"]
console.log(solution(str))

 

소문자로 된 단어(문자열)가 입력되면 그 단어의 가운데 문자를 출력하는 프로그램을 작성하세
요. 단 단어의 길이가 짝수일 경우 가운데 2개의 문자를 출력합니다.
▣ 입력설명
첫 줄에 문자열이 입력된다. 문자열의 길이는 100을 넘지 않습니다.
▣ 출력설명
첫 줄에 가운데 문자를 출력합니다.
▣ 입력예제 1
study
▣ 출력예제 1
u
▣ 입력예제 2
good
▣ 출력예제 2
oo

 

풀이 이것도 그냥 하라는대로 하면 된다.
문자열 길이를 이용해서 짝수 홀수 판별하고 함수를 이용하면 편하다.

Math.floor(x)인수보다 작거나 같은 수 중에서 가장 큰 정수를 반환합니다.(내림)

Math.round(x)숫자에서 가장 가까운 정수를 반환합니다.(반올림)

Math.ceil(x)인수보다 크거나 같은 수 중에서 가장 작은 정수를 반환합니다.(올림)


substr(시작 index, 가져올 문자열 갯수)

substring(시작 index, 끝 idex +1)

[출처] [자바스크립트, JavaScript] 형변환(1) - Number(),parseInt(),parseFloat() + 슬라이싱(substr(), substring())|작성자 nyjchoi

function solution(s){
    let answer;
    let mid=Math.floor(s.length/2)
    if(s.length%2 ==1 ) {
        answer = s.substr(mid,1)
    }else {
        answer = s.substr(mid-1,2)
    }
    return answer
}
console.log(solution("length"))

'Today I Learned' 카테고리의 다른 글

11 TIL 리액트의 날  (0) 2021.09.27
10 TIL 2 WIL REST, Restful API, GraphQL 차이 장단점 , DOM, 서버리스, 파이어베이스  (0) 2021.09.26
7 TIL  (0) 2021.09.23
6 TIL  (0) 2021.09.23
4 TIL 항해 8일차  (0) 2021.09.20

휴 기본 과제를 끝냈다
이번엔 개인과제라서 엄청 마음 편하게 할 수 있었던 것 같다.

https://github.com/shinsw627/basicCrud.git

다음 주 수요일 까지라서 굉장히 시간이 여유롭지만 빨리 끝내고 다른 공부를 하고 싶어서 후다닥 정리해버렸다.
완전히 기능 중심으로만 구현 하였고(CRUD만...) 디자인은 전혀 신경쓰지 않았다.

이런식으루 간단히 조회되고
글의 제목이나 내용을 클릭하면

이런식으로 detail페이지로 이동한다.
수정하기를 누르면 수정페이지가 나오고 원래 글의 내용이 적혀있고 글에 설정했던 비밀번호를 입력해서 수정할 수 있다.

삭제하기를 눌렀을 경우

간단한 모달 창이뜨고 비밀번호를 입력해서 삭제할 수 있다.

const express = require('express')
const app = express()
const port = 3000

app.use(express.urlencoded({extended: false}))
app.use(express.json())

const connect = require('./schemas');
connect();

const postsRouter = require('./routers/posts')
app.use('/api', postsRouter)

app.use(express.static('public'));


app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

// app.use((req, res, next) => {  미들웨어     console.log(req);     next();   });

app.get('/hi', (req, res) => {
    res.send('Hi. This is express router')
})

app.get('/', (req, res) => {
    res.render('index')
})

app.get('/write',(req, res) => {
    res.render('write')
  })

app.get('/detail', (req, res) => {
let postId = req.query.name;
res.render('detail', {postId});
})
app.get('/rewrite', (req, res) => {
let postId = req.query.name;
res.render('rewrite', {postId});
})

app.listen(port, () => {
    console.log(`listening at http://localhost:${port}`)
})
const express = require("express");
const Posts = require("../schemas/posts");

const router = express.Router();

router.get("/posts", async (req, res, next) => {
  try {
    
    const posts = await Posts.find({}).sort("-postId");
    res.json({ posts: posts });
  } catch (err) {
    console.error(err);
    next(err);
  }
});

router.get("/posts/:postId", async (req, res) => {
  const { postId } = req.params;
  posts = await Posts.findOne({ postId: postId });
  res.json({ posts: posts });
});

//글 작성
router.post('/write', async (req, res) => {
    const { postId, userName, title, content, contentPw, date } = req.body;
    await Posts.create({ postId, userName, title, content, contentPw, date });
    
    res.send({ result: "success" });
  });

//글 수정 PATCH
router.patch("/posts/:postId", async (req, res) => {
  console.log(req.params)
  const { postId } = req.params;
  const { title, content } = req.body;
  const loadpost = await Posts.find({ postId });
  console.log(loadpost)
  if (loadpost.length > 0) {
      await Posts.updateOne({ postId } , { $set: { title, content }})
  }
  res.send({ result: "success" });
})

//글 삭제 DELETE
router.delete("/posts/:postId", async (req, res) => {
  const {postId } = req.params

  const deletePost = await Posts.find({ postId });
  if(deletePost.length > 0){
      await Posts.deleteOne({ postId });
  }
  res.send({result: "success" });
})

module.exports = router;



간단한crud여서 어렵진 않았다.
빨리 심화수업을 듣고 싶은데 너무 아쉽다.
좀 더 공부할 것을 찾아봐야겠다.

실전프로젝트 음악도 빨리 준비 할 것!

 

오히려 배포하는 데에 오류가 생겼어서 간단히 명령어를 정리해 보았다.

 

sudo iptables -t nat -L //현재 ip설정 확인

sudo iptables -t nat -D PREROUTING 1 //설정된거 젤위에꺼 하나 지우기(기존 5000포트가 80포트로 접속하던거를 지우기)

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000 //80포트 3000으로 바꾸기


sudo apt-get install -y nodejs //node 설치

 

pm2 설치 관련
sudo -s //관리자 권한 취득

npm install -g pm2 //pm2 설치

pm2 start 파일이름 //pm2로 파일 실행

pm2 stop 파일이름 //pm2 파일 종료

알고리즘 시간!

한 개의 문자열을 입력받아 해당 문자열에 알파벳 대문자가 몇 개 있는지 알아내는 프로그램
을 작성하세요.
▣ 입력설명
첫 줄에 문자열이 입력된다. 문자열의 길이는 100을 넘지 않습니다.
▣ 출력설명
첫 줄에 대문자의 개수를 출력한다.
▣ 입력예제 1
KoreaTimeGood
▣ 출력예제 1
3

풀이

toUpperCase()를 이용해서 같은 원본과 비교하는 형태로 풀면된다. 쉽다!!

function solution(str){
    let answer=0;
    for(let a of str) {
        if(a == a.toUpperCase()){
            answer++;
        }
       
    }
    return answer
}
let str="KoreaTimeGood"
console.log(solution(str))

 

대문자와 소문자가 같이 존재하는 문자열을 입력받아 대문자로 모두 통일하여 문자열을 출력
하는 프로그램을 작성하세요.
▣ 입력설명
첫 줄에 문자열이 입력된다. 문자열의 길이는 100을 넘지 않습니다.
▣ 출력설명
첫 줄에 대문자로 통일된 문자열이 출력된다.
▣ 입력예제 1
ItisTimeToStudy
▣ 출력예제 1
ITISTIMETOSTUDY

풀이

아까랑 거의 똑같은 문제다 반대로 소문자로 만들어서 비교하고 같으면 대문자로 전환해서 answer에 더하고
다르면 그냥 answer에 더했다.

function solution(str){
    let answer="";
    for(let a of str) {
        if(a === a.toLowerCase()){
            answer += a.toUpperCase();
        } else {
            answer += a;
        }
       
    }
    return answer
}
let str="KoreaTimeGood"
console.log(solution(str))

 

다른 풀이인 아스키코드로 하는 방법도 있어서 가져와봤다.

function solution(str){
    let answer="";
    for(let a of str) {
        if(a == a.toLowerCase()){
            answer += a.toUpperCase();
        } else {
            answer += a;
        }
       
    }
    return answer
}
let str="KoreaTimeGood"
console.log(solution(str))

아스키코드 

중요한건 65부터 90 까지가 대문자이고 
97부터 122까지가 소문자 이다. 
대문자에서 32를 더하면 소문자가 된다!

게시판 만드는 과제를 하기 위해
처음 서버 만들기부터 다시 시작하였다...
생각보다 어려워서 내가 아직 개념이해가 많이 부족하다는 것을 뼈저리게 느꼈다...

그리고 html css... 너무 어려워~~ 노잼노잼

const express = require('express')
const app = express()
const port = 3000



const connect = require('./schemas');
connect();

const postsRouter = require('./routers/posts')
app.use('/api', postsRouter)

app.use(express.urlencoded({extended: false}))
app.use(express.json())
app.use(express.static('public'));


app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

// app.use((req, res, next) => {  미들웨어     console.log(req);     next();   });

app.get('/hi', (req, res) => {
    res.send('Hi. This is express router')
})

app.get('/', (req, res) => {
    res.render('index')
})



app.listen(port, () => {
    console.log(`listening at http://localhost:${port}`)
})
$(document).ready(function() {
            get_posts()
        })

        function get_posts() {
            $("#postsList tbody").empty()
            
            $.ajax({
                type: "GET",
                url: `/api/posts`,
                data: {},
                success: function (response) {
                    let posts = response["posts"]
                    console.log(posts)
                    for ( let i = 0; i < posts.length; i++) {
                        make_list(posts[i],i+1)
                    }
                }
            })

        }
        function make_list(item, i) {
            let previewContent = item['content'].substring( 0, 25 )
            
            let htmlTemp = `<tr>
                                <th scope="row">${i}</th>
                                <td>${item['userName']}</td>
                                <td>${item['title']}</td>
                                <td><a>${previewContent}...</a></td>
                            </tr>`
            $("#postsList tbody").append(htmlTemp)
        }

 

정말 처음이라 겨우겨우 게시판 조회를 만들어 봤다.
백에서 보내는 것까진 재밌게 했는데 프론트부분을 하려니 막막했다.
html css도 손에 익도록 쫌 연습해야겠다.

 

어느정도 틀은 만들어 놨기 때문에 내일은 빠르게 쓰기랑 수정을 구현해야겠다.

 

 

알고리즘 시간!

대문자로 이루어진 영어단어가 입력되면 단어에 포함된 ‘A'를 모두 ’#‘으로 바꾸어 출력하는
프로그램을 작성하세요.
▣ 입력설명
첫 번째 줄에 문자열이 입력된다.
▣ 출력설명
첫 번째 줄에 바뀐 단어를 출력한다.
▣ 입력예제 1
BANANA
▣ 출력예제 1
B#N#N#

풀이.

음 너무 간단하다. 그냥 포문돌리면서 answer에다가 기존 값이 A일경우는 #을 넣고 아닐경우에는 기존 값을 넣는 식으로 했다.

function solution(s){
                let answer="";
                for(let x of s){
                    if(x=='A') answer+='#';
                    else answer+=x;
                }
                return answer;
            }
            
            let str="BANANA";
            console.log(solution(str));

 

한 개의 문자열을 입력받고, 특정 문자를 입력받아 해당 특정문자가 입력받은 문자열에 몇 개
존재하는지 알아내는 프로그램을 작성하세요.
문자열의 길이는 100을 넘지 않습니다.
▣ 입력설명
첫 줄에 문자열이 주어지고, 두 번째 줄에 문자가 주어진다.
▣ 출력설명
첫 줄에 해당 문자의 개수를 출력한다.
▣ 입력예제 1
COMPUTERPROGRAMMING
R
▣ 출력예제 1
3

풀이

이것도 똑같다... 포문돌려서 같으면 answer++... 오히려 더 쉽다.

function solution(s, t){
                let answer=0;
                for(let x of s){
                    if(x===t) answer++;
                }
                return answer;
            }
            
            let str="COMPUTERPROGRAMMING";
            console.log(solution(str, 'R'));

하지만 split 함수를 이용해서 하나를 빼는 방법도 있다.

function solution(s, t){
                let answer=s.split(t).length;
                return answer-1;
            }
            
            let str="COMPUTERPROGRAMMING";
            console.log(solution(str, 'R'));

 

'Today I Learned' 카테고리의 다른 글

10 TIL 2 WIL REST, Restful API, GraphQL 차이 장단점 , DOM, 서버리스, 파이어베이스  (0) 2021.09.26
9TIL 항해99 13일차  (0) 2021.09.25
6 TIL  (0) 2021.09.23
4 TIL 항해 8일차  (0) 2021.09.20
3 TIL & WIL  (0) 2021.09.19

어제 심각한 DB오류와(2시간 가량 시간 버림 ㅠ) 멍청하게 vscode에서 작성을 해놓고 저장을 안하고 구동을 계속해서 (3시간 날림... 파이참은 저장안해도 실시간으로 반영되던데 ㅠㅠ) 3주차를 전부 듣지 못했다.
생각해보니 알고리즘도 못해서 오늘 두배로 해야한다...

일단 시작 전에 그냥 동기 비동기 기본 지식은 알아야할 거 같아서 뜬금없이 저장해봣다.
동기, 비동기 처리 (velog.io)

 

동기, 비동기 처리

데이터를 처리하는 방식인 동기, 비동기 처리에 대해 많은 글이 있지만 정확하게 와닿지가 않았다. 최대한 내가 이해한 방식대로 서술해 보려고 한다. 동기 (Synchronous)는 요청과 동시에 일어난다

velog.io

[Javascript] 🌟비동기 처리🌟 (velog.io)

 

[Javascript] 🌟비동기 처리🌟

앞의 글에서 동기와 비동기의 간단한 개념을 살펴 보았다. 자바스크립트의 동기 비동기 또한 개념은 같다.특정 코드의 연산이 끝날 때 까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하

velog.io

글 쫌 잘쓰시네 ㅎㅎ;

https://velog.io/@sujin19/node.js-REST-api-mongoDB

 

node.js (REST api, mongoDB)

Representational State TransferREST라는 규칙을 따르는 APIWorld Wide Web과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식웹에 존재하는 모든 자원(이미지, 동영상, DB자원)에 고유한

velog.io

기본적인 것 되새기기!!! 

- 뜬금 arrow function 되새기기 -
const 익명함수이름쓰 = (변수) =>{ 함수내용이다!}
평소에 잘 못보던 폼이라 헷갈렸었기 때문에 ㅎㅎ...

 

어제 상황에서 우선 POST 상품 불러오기를 추가하였다.

router.post('/goods', async (req, res) => {
    const { goodsId, name, thumbnailUrl, category, price } = req.body;
  
    isExist = await Goods.find({ goodsId }); //같은거 있는지 확인
    if (isExist.length == 0) {  //없으면 생성
      await Goods.create({ goodsId, name, thumbnailUrl, category, price });
    }
    res.send({ result: "success" });
  });

그리고 insomnia를 설치하여 다른 메소드(POST)를 호출해보았다.

잘 된다.

굿즈를 카트에 담고 장바구니 페이지에 보여주도록 만들었다.

//카트 정보 post
  router.post("/goods/:goodsId/cart", async (req, res) => {
    const { goodsId } = req.params;
    const { quantity } = req.body;
  
    isCart = await Cart.find({ goodsId });
    console.log(isCart, quantity);
    if (isCart.length) {
      await Cart.updateOne({ goodsId }, { $set: { quantity } });
    } else {
      await Cart.create({ goodsId: goodsId, quantity: quantity });
    }
    res.send({ result: "success" });
  });
  
  //장바구니에 정보 쏴주는거
  router.get("/cart", async (req, res) => {
    const cart = await Cart.find({});
    const goodsId = cart.map(cart => cart.goodsId);
  
    goodsInCart = await Goods.find()
      .where("goodsId")
      .in(goodsId);
  
    concatCart = cart.map(c => {
      for (let i = 0; i < goodsInCart.length; i++) {
        if (goodsInCart[i].goodsId == c.goodsId) {
          return { quantity: c.quantity, goods: goodsInCart[i] };
        }
      }
    });
  
    res.json({
      cart: concatCart
    });
  });

이번엔 장바구니에 있는 정보를 지우는 api를 추가했다.(delete)

router.delete("/goods/:goodsId/cart", async (req, res) => {
      const {goodsId } = req.params

      const isGoodsInCart = await Cart.find({ goodsId });
      if(isGoodsInCart.length > 0){
          await Cart.deleteOne({ goodsId });
      }
      res.send({result: "success" });
  })

장바구니에 수량 변경하는 api를 추가했다 (patch)

  //장바구니 수량 변경
router.patch("/goods/:goodsId/cart", async (req, res) => {
    const { goodsId } = req.params;
    const { quantity } = req.body;

    const isGoodsInCart = await Cart.find({ goodsId });
    console.log(isGoodsInCart)
    if (isGoodsInCart.length > 0) {
        await Cart.updateOne({ goodsId }, { $set: { quantity}})
    }
    res.send({ result: "success" });
})

 

====================================================
node.js로 크롤링 하는 법에 대해 배웠다.

1) Node.js 서버에서 외부에 있는 특정 웹사이트에 접근 ⇒ axios
2) 특정 웹사이트 HTML 코드를 가져와 조작하기 ⇒ cheerio
3) 한글 깨짐 방지! ⇒ iconv-lite

npm install axios cheerio iconv-lite -s

설치 후에

크롤링을 하여 DB에 저장하는 부분을 만들었다.

router.get("/goods/add/crawling", async (req, res) => {
  try {
    //크롤링 대상 웹사이트 HTML 가져오기
    await axios({
      url: url,
      method: "GET",
      responseType: "arraybuffer",
    }).then(async (html) => {
        //크롤링 코드
      const content = iconv.decode(html.data, "EUC-KR").toString();
      const $ = cheerio.load(content);
      const list = $("ol li");

      await list.each( async (i, tag) => {
        let desc = $(tag).find("p.copy a").text() 
        let image = $(tag).find("p.image a img").attr("src")
        let title = $(tag).find("p.image a img").attr("alt")
        let price = $(tag).find("p.price strong").text()
      
        if(desc && image && title && price){
          price = price.slice(0,-1).replace(/(,)/g, "")
          let date = new Date()
          let goodsId = date.getTime()
          await Goods.create({
            goodsId:goodsId,
            name:title,
            thumbnailUrl:image,
            category:"도서",
            price:price
          })
        }
  
      });
    })
    res.send({ result: "success", message: "크롤링이 완료 되었습니다." });

  } catch (error) {
    //실패 할 경우 코드
    res.send({ result: "fail", message: "크롤링에 문제가 발생했습니다", error:error });
  }
});

 

어제 까먹고 못한 ㅠ 알고리즘까지 두 문제를 했다.

서울시는 6월 1일부터 교통 혼잡을 막기 위해서 자동차 10부제를 시행한다. 자동차 10부제는
자동차 번호의 일의 자리 숫자와 날짜의 일의 자리 숫자가 일치하면 해당 자동차의 운행을 금
지하는 것이다. 예를 들어, 자동차 번호의 일의 자리 숫자가 7이면 7일, 17일, 27일에 운행하
지 못한다. 또한, 자동차 번호의 일의 자리 숫자가 0이면 10일, 20일, 30일에 운행하지 못한
다.
여러분들은 일일 경찰관이 되어 10부제를 위반하는 자동차의 대수를 세는 봉사활동을 하려고
한다. 날짜의 일의 자리 숫자가 주어지고 7대의 자동차 번호의 끝 두 자리 수가 주어졌을 때
위반하는 자동차의 대수를 출력하는 프로그램을 작성하세요.

▣ 입력설명
첫 줄에는 날짜의 일의 자리 숫자가 주어지고 두 번째 줄에는 7대의 자동차 번호의 끝 두 자
리 숫자가 주어진다.
▣ 출력설명
주어진 날짜와 자동차의 일의 자리 숫자를 보고 10부제를 위반하는 차량의 대수를 출력합니
다.

풀이

10으로 나눈 나머지가 일수 이므로 이를 이용해서 푼다 넘쉽!

function solution(day, arr){
    let answer = 0;
    for(let car of arr){
        if (car % 10 === day){
            answer++
        }
    }
    return answer
}

arr = [25, 23, 11, 47, 53, 17, 33];
console.log(solution(3,arr));

 

왕비를 피해 일곱 난쟁이들과 함께 평화롭게 생활하고 있던 백설공주에게 위기가 찾아왔다.
일과를 마치고 돌아온 난쟁이가 일곱 명이 아닌 아홉 명이었던 것이다.
아홉 명의 난쟁이는 모두 자신이 "백설 공주와 일곱 난쟁이"의 주인공이라고 주장했다. 뛰어난
수학적 직관력을 가지고 있던 백설공주는, 다행스럽게도 일곱 난쟁이의 키의 합이 100이 됨을
기억해 냈다.
아홉 난쟁이의 키가 주어졌을 때, 백설공주를 도와 일곱 난쟁이를 찾는 프로그램을 작성하시
오.
▣ 입력설명
아홉 개의 줄에 걸쳐 난쟁이들의 키가 주어진다. 주어지는 키는 100을 넘지 않는 자연수이며,
아홉 난쟁이의 키는 모두 다르며, 가능한 정답이 여러 가지인 경우에는 아무거나 출력한다.
▣ 출력설명
입력된 순서대로 일곱 난쟁이의 키를 출력한다.

풀이

대충 푸는 방법은 9개의 수를 모두 더한 값에서 아무나 두명을 뽑아서 빼면 100이 나오도록 하는 것이다.

마지막 배열에서 splice를 사용할때 뽑은 수가 4번 5번이라면 
4번부터 빼버리면 5번째숫자는 자연히 4번째가 되므로 5번째를 빼버리면 계산이 오류가 나게 되어버린다
그러므로 뒤에 뽑은 수를 먼저 빼어서 그런 오류를 범하지 않게 하여야한다.

function solution(arr){
    let answer = arr;
    let sum =  0;
    for(let nan of arr){
        sum+=nan

    }
    console.log(sum)
    for (let i =0; i < arr.length-1; i++){
        for(let k = i+1; k < arr.length; k++){
            if(sum - (arr[i] + arr[k]) === 100){
                answer.splice(k, 1)
                answer.splice(i, 1)
                 
            }
        }
        
    }
    
    return answer
}

arr = [20, 7, 23, 19, 10, 15, 25, 8, 13];
console.log(solution(arr));

 

forEach

자바스크립트에서 제공하는 배열(Array)의 유용한 함수 (reduce, map, filter, indexOf, foreach) (tistory.com)

 

자바스크립트에서 제공하는 배열(Array)의 유용한 함수 (reduce, map, filter, indexOf, foreach)

자바스크립트(javascript)에서 제공하는 배열의 함수 ES6에서만 사용하는 것은 아니지만 자바스크립트 프로그래밍할 때 유용한 메서드이면서 다른 사람의 코드를 보면서 이해를 못했던 필자 같은

jeong-pro.tistory.com

 

 

'Today I Learned' 카테고리의 다른 글

9TIL 항해99 13일차  (0) 2021.09.25
7 TIL  (0) 2021.09.23
4 TIL 항해 8일차  (0) 2021.09.20
3 TIL & WIL  (0) 2021.09.19
2 TIL  (0) 2021.09.19

항해로운 항가위를 맞이하였다. 오지게 node 강의 듣자@@@@

Express - Routing.

같은 도메인 주소지만 url 주소의 뒷부분인 path 정보에 따라 다른 결과가 보여지게 하는 것이다.
https://spartacodingclub.kr/online/webplus       https://spartacodingclub.kr/portfolio

 

스파르타코딩클럽 [웹개발 플러스]

로그인, 지도, 소셜미디어 만들기

spartacodingclub.kr

app.get('/', (req, res) => {
  res.send('Hello World!')
})
app.get('/hi', (req, res) => {
  res.send('Hi. This is express router')
})

라우터객체 사용하기.

const express = require('express')
const app = express()
const port = 3000

const goodsRouter = require('./routes/goods')
const userRouter = require('./routes/user')

app.use('/goods', goodsRouter)
app.use('/user', userRouter)

// app.get('/goods/list', (req, res) => {
//     res.send('상품 목록 페이지')
//   })
  
//   app.get('/goods/detail', (req, res) => {
//     res.send('상품 상세 페이지')
//   })
  
//   app.get('/user/login', (req, res) => {
//     res.send('로그인 페이지')
//   })
  
//   app.get('/user/register', (req, res) => {
//     res.send('회원가입 페이지')
//   })

app.listen(port, () => {
  console.log(`listening at http://localhost:${port}`)
})

바로 위 예시에서 모든 라우팅을 한페이지에 쭉 나열한다면 가독성도 엄청 떨어지고 정말 어지럽게 될 것이다.

그래서 라우터를 이용하여

var express = require('express');
var router = express.Router();

  router.get('/login', (req, res) => {
    res.send('로그인 페이지')
  })
  
  router.get('/register', (req, res) => {
    res.send('회원가입 페이지')
  })

module.exports = router;
var express = require('express');
var router = express.Router();

router.get('/list', function (req, res, next) {
    res.send('Router 상품 목록 페이지')
});

router.get('/detail', function (req, res, next) {
    res.send('Router 상품 상세 페이지')
});

module.exports = router;

user.js goods.js 와 같은 형태로 나누어서 처리를 하면 깔끔해진다.

 

미들웨어.
유저 인증과 같은 반복되는 작업들, 혹은 우리가 정의한 route에 오기 전에 중간에서 미리 처리해야할 것들을 정의해둔 것을 미들웨어라고 한다.

const express = require('express');
const app = express();

app.use((req, res, next) => {
  console.log(req);
  next();
});

app.get('/', (req, res, next) => {
  res.send('Welcome Home');
});

app.listen(3000);

이런 코드가 있다면 중간에 app.use 라고 하는 것이 미들웨어를 쓰겠다. 라는 것이다. 저 코드를 사용하면 어떤 요청이 들어오던 간에 req를 로그로 찍고 나서 실제 route로 전달되게 된다.
그 후에 next()를 실행해 다음 미들웨어로 순차적으로 진행된다.

이런식으로 들어온 요청은 우리가 설정한 미들웨어를 통과하고 중간에 응답을 해서 종료가 되거나 아니면 다음 미들웨어가 있는 경우에는 다음 미들웨어로 넘어간다.

 

express.json() , express.urlencoded()

우리는 웹서버에 요청할 때 단순히 url 외에 추가적인 정보를 전달 할 수 있다. POST 메서드의 body 정보가 그것이다. 이것을 express 에서 사용하려면 복잡한 절차가 필요하게 된다. 이 데이터를 바로 사용하기 쉽게 가공해주는 미들웨어가 바로 이 express.json()이다.
- POST메서드의 정보들을 절차에 맞게 쉽게 가공하는 미들웨어 -

app.use(express.urlencoded({extended: false}))
app.use(express.json())

 

Static.
Express의 기본 제공 미들웨어이며 Express 애플리케이션의 정적 자산을 제공하는 역할을 하는 static이다. 이것을 이용하면 우리의 express에서도 이쁜 이미지, 신나는 동영상 같은 정적 파일은 제공할 수 있다.

app.use(express.static('public'));

 

Template engine.
템플릿 엔진을 사용하면 일관된 양식의 HTML 파일에다가 그때그때 원하는 데이터를 동적으로 삽입해서 우리가 원하는 형태의 홈페이지를 구성할 수 있게 된다.

템플릿 엔진의 장점

  1. 많은 코드를 줄일 수 있다. → 대부분의 Template Engine은 기존의 HTML에 비해서 간단한 문법을 사용한다.
  2. 재사용성이 높다. → 웹페이지 혹은 웹앱을 만들 때 똑같은 디자인의 페이지에 보이는 데이터만 바뀌는 경우가 굉장히 많다.
  3. 유지보수에 용이하다. → 하나의 Template을 만들어 여러 페이지를 렌더링하는 작업에는 또 다른 이점이 있다.

템플릿 엔진 - ejs 설치.

$ npm install ejs

혹시 [ERROR] npm WARN text@1.0.0 No description | npm WARN text@1.0.0 No repository field 이런 식의 에러가 뜬다면 다음 블로그를 참조해서 package.json파일에 다음과 같이 "private": true, 를 입력해주면 설치가 잘 된다.

 

[ERROR] npm WARN text@1.0.. : 네이버블로그 (naver.com)

 

[ERROR] npm WARN text@1.0.0 No description | npm WARN text@1.0.0 No repository field

웹에 실시간 영상을 띄우는 개발을 하는 도중 node js를 다운로드 받아 cmd 창에서 실행하던 도중 만난 에...

blog.naver.com

 

app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

app.get('/test', (req, res) => {
  let name = req.query.name;
  res.render('test', {name});
})

render 하여 test 와 {name} 두 개의 인자를 넘겨준다.
이는 test.ejs를(html형태를) 그리고 그 ejs 파일에 name 값을 객체로 넘겨주겠다는 의미이다!!

그 후 views 폴더를 생성하고 test.ejs 파일을 추가하였다.

test.ejs
<!DOCTYPE html>
<html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
  </head>
  <body>
      Hi. My name is <%= name %><br>
  </body>
</html>

http://localhost:3000/test?name=NyanNyan 이런식으로 입력하게 되면 
name 정보를 전달하여
Hi. My name is NyanNyan
을 띄우게 된다.

REST 
REST(Representational State Transfer)는 월드 와이드 웹과 같으 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식이다.
웹에 존재하는 모든 자원(이미지, 동영상, DB 자원) 에 고유한 URL를 부여해 활용 하는 것으로, 자원을 정의하고 자원에 대한 주소를 지정하는 방법론.
https://velog.io/@meekukin/RESTful-API-4uk5rtheqv

 

RESTful API

image.png RESTful API란? REST는 Representational State Transfer의 약자로 소프트웨어 프로그램 아키텍처의 한 형식이다. 웹에 존재하는 모든 자원(이미지, 동영상, DB 자원) 에 고유한 URI를 부여해 활용하는 것

velog.io

  1. 자원(Resource) - URL
    • 우리가 만들 소프트웨어가 관리하는 모든 것을 자원으로 표현할 수 있습니다. 쇼핑몰이라면 상품(Goods)에 대해서 정보를 관리할것이고 또는 장바구니(Carts)에 담긴 상품들도 관리해야겠죠.
  2. 행위 - HTTP method
    • 이전에 배웠던 HTTP method 기억나시나요? GET, POST 등등이 있다고 했었는데요. 이것으로 해당 자원에 대한 행위를 표현할 수 있습니다. 예를 들어 GET 메소드는 해당 자원의 조회, POST 메소드는 해당 자원의 생성 이런 식으로요.
    • 이렇게 나누어진 것을 보통 CRUD 라고 합니다. 자원에 대한 생성/조회/수정/삭제를 각각의 method 로 나누어놓은 것이지요.Create : 생성(POST) Read : 조회(GET) Update : 수정(PUT) Delete : 삭제(DELETE)
    • 위 이미지의 예시처럼 쓰이는 것이 일반적인 method 사용방식입니다. 하지만 이것은 필수인 부분이 아니고 모든 곳에서 다 이렇게 지켜서 사용하지는 않습니다. 상황에 따라 저것을 완벽하게 지키기 어려운 부분들도 있으니 이 부분 참고 해주세요.
  3. 표현
    • 해당 자원을 어떻게 표현할지에 대한 설명입니다. 보통 JSON, XML 같은 형식을 이용해서 자원을 표현합니다.

DB.
데이터베이스란 데이터를 안전하고 편리하게 보관하고 가져다가 쓸 수 있는 서비스입니다.

RDBMS(SQL)
행/열의 생김새가 정해진 엑셀에 데이터를 저장하는 것과 유사하다. 데이터 50만 개가 적재된 상태에서, 갑자기 중간에 열을 하나 더하기는 어렵다. 그러나, 정형화 되어 있는 만큼, 데이터의 일관성이나 분석에 용이하다.
ex) MS-SQL, My-SQL 등

No-SQL
딕셔너리 형태로 데이터를 저장해두는 DB이다. 고로 데이터 하나하나 마다 같은 값들을 가질 필요가 없게 된다. 자유로운 형태의 데이터 적재에 유리한 대신, 일관성이 부족할 수 있다.

mongoose
mongoose 는 mongoDB에 연결하고 데이터 모델링을 제공해주는 툴이다.

npm install mongoose

api 추가하기. (내일로 이어짐 ㅠ)

goods route 생성

const goodsRouter = require("./routers/goods");
app.use("/api", [goodsRouter]);

 

키워드 수를 적어도 50개 이상으로 생각 중이다.... 가능할까? ㅠ

장소나 상태에 관한 키워드
비오는날5, 밤2, 별3, 달3, 드라이브2, 새벽2, 봄2, 여름2, 가을2, 겨울2, 산책2, 산3, 숲2, 운동3, 클럽5, 카페3, 버스3, 라운지2, 강2, 바다3, 캠핑3, 노을2, 첫사랑3, 파티3, 크리스마스5, 야자수3, 공부2, 도심4, 벛꽃3, 눈2, 일출2, 일몰2, 썸2, 여행4

감정에 관한 키워드 
밝음
사랑3, 달달3, 연애3, 신나는3, 흥분3, 맑은2, 설렘3, 기분좋은2, 일탈3, 행복2, 춤4, 자존감상승3, 럭셔리3, 

어두움
실연3, 우울3, 슬픔3, 다크3, 분노3, 멍, 아픔3, 자존감하락3, 열등감4, 지침3,

중간 조용
기다림2, 감성2, 센치3,  잔잔한2, 짝사랑4, 추억3, 몽환4,

 

특별 키워드
히어로4, 빌런4, 총3, 퇴폐미4, 섹쉬4, 꿀보이스4, 싸이코패스4, 레트로4, 

노래에 관한 키워드
베이스꿍꿍4, 일렉트릭4, 

장르에 관한 키워드
가요5, POP5, 힙합6, 재즈7, 발라드5, 댄스4, 인디5, R&B/Soul4, 랩8, 트로트6, 포크/블루스5, ASMR5, 뉴에이지5, 씨티팝7, 클래식 6, 

MBTI???(고려중)

 

'실전프로젝트 구상' 카테고리의 다른 글

실전프로젝트 구상 중 수정 3  (0) 2021.09.19

드디어 주특기 node.js 강의에 들어갔다

자바스크립트 하면서 느낀점은 '비교적 쉽고 재미있다!' 이다. 자바를 배우다가 파이썬을 처음 배울 때랑 비슷한거 같다.ㅎ ㅎ;

1주차 밖에 끝내지 못했다... 내일은 진짜 일찍 일어나서(새벽5시반쯤) 제대로 들어서 3주차까지 끝내야겠다. 모레는 5주차!!!!!! 제대로 달리자!!!!!!!!!!

var, let, const 비교

 

var, let, const 비교

A new tool for teams & individuals that blends everyday work apps into one.

www.notion.so

 

호이스팅이란? Hoisting

ES6에서 가장 크게 변화된 요소 중 하나라고 할 수 있다.
Hoisting 이란 함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것을 말한다.
var 변수가 영향을 많이 받아서 가끔 프로그램이 의도한대로 동작하지 않을 때가 있다. 그래서 요즘에는 var를 쓰지않고 let이나 const를 사용한다.

  • 함수 내에서 아래 쪽에 존재하는 내용 중 필요한 값들을 끌어올리는 것이다!
  • 하지만 실제로 코드가 끌어올려지는 게 아니라, 자바스크립트 parser 내부적으로 끌어올려서 처리하는 것이다!

es6에서 추가된 for문

const students = ["John","Jane","Alex"]

for (let student of students) {
    console.log(student)
}

for (let index in students){
    console.log(index)
}

students.forEach((student) => {
    console.log(student)
})

for of 가 파이썬에서의 for in 느낌인거 같고
for in 은 리스트의 인덱스번호를 순서대로 가져오는거고
forEach함수가 for of랑 같은 형태라고 보면 된다.

Arrow Functions.

function hello() {
	console.log("Hello function");
}

// 첫번째 arrow function
const arrowFunction = () => {
	console.log("Hello arrow function");
}

// 두번째 arrow function
const arrowFunctionWithoutReturn = () => console.log("Hello arrow function without return");

 

function hello(message) {
	console.log(message);
}

// 첫번째 arrow function
const arrowFunction = (message) => {
	console.log(message);
}

// 두번째 arrow function
const arrowFunctionWithoutReturn = (message) => console.log(message);

Arrow Functions 문제

let personArray = [
    {"name": "John Doe", "age": 20},
    {"name": "Jane Doe", "age": 19},
    {"name": "Fred Doe", "age": 32},
    {"name": "Chris Doe", "age": 45},
    {"name": "Layla Doe", "age": 37},
];

// personArray의 나이 평균을 구해주는 Arrow Function을 작성해봅시다.
const getAgeAverage = (personArray) => {
    let sum = 0
    for (let person of personArray){
        sum += person['age']
    }
    let average = sum/personArray.length
    return average

}

console.log(getAgeAverage(personArray));

Promise.

콜백 지옥이란??
버스를 타는 과정을 여러단계로 나눈다면 이렇게 생각해볼 수 있다.

  1. 버스를 기다린다(isBusHere).
  2. 버스가 정류장에 도착한다(isBusStop).
  3. 버스 문이 열린다(isDoorOpen).
  4. 지갑을 찾는다(findWallet).
  5. 지갑에 교통카드를 찾는다(findCard).
  6. 교통카드로 버스요금을 낸다(payBusFare).
isBusHere(function(isBusHereResult) {
  isBusStop(isBusHereResult, function(isBusStopResult) {
    isDoorOpen(isBusStopResult, function(isDoorOpenResult) {
      findWallet(isDoorOpenResult, function(isWalletHere) {
        findCard(isWalletHere, function(isCardHere) {
          payBusFare(isCardHere, function() {
            // 드디어 결제가 성공했네요...
          }, failureCallback);
        }, failureCallback);
      }, failureCallback);
    }, failureCallback);
  }, failureCallback);
}, failureCallback);

하하하,  극단적인 callback 예시이다.
이런 중첩 콜백지옥 현상을 해결해 주는 것이 Promise다

isBusHere()
.then(function(isBusHereResult) {
    return isBusStop(isBusHereResult)
})
.then(function(isBusStopResult) {
    return isDoorOpen(isBusStopResult)
})
.then(function(isDoorOpenResult) {
    return findWallet(isDoorOpenResult)
})
.then(function(isWalletHere) {
    return findCard(isWalletHere)
})
.then(function(isCardHere) {
    return payBusFare(isCardHere)
})
.catch(failureCallback);

여기서 Arrow Function 까지 같이 써주면 가독성이 더 좋아진다.

isBusHere()
  .then(isBusHereResult => isBusStop(isBusHereResult))
  .then(isBusStopResult => isDoorOpen(isBusStopResult))
  .then(isDoorOpenResult => findWallet(isDoorOpenResult))
  .then(isWalletHere => findCard(isWalletHere))
  .then(isCardHere => payBusFare(isCardHere))
  .catch(failureCallback);

promise의 기본적인 형태

const isReady = true;
// 1. Producer
const promise = new Promise((resolve, reject) => {
  console.log("Promise is created!");
  if (isReady) {
    resolve("It's ready");
  } else {
    reject("Not ready");
  }
});

// 2. Consumer
promise
  .then(messsage => {
    console.log(messsage);
  })
  .catch(error => {
    console.error(error);
  })
  .finally(() => {
    console.log("Done");
  });

// Promise is created!
// It's ready
// Done

Pending(대기): 아래와 같이 Promise가 처음 생성되면 pending(대기) 상태가 됩니다.

const promise = new Promise((resolve, reject) => {});

console.log(promise);

// Promise { <pending> }

Fulfilled(이행): 아래와 같이 Promise에서 resolve를 실행하면 Fulfilled(이행) 상태가 됩니다.

 

const promise = new Promise((resolve, reject) => {
	resolve();
});

console.log(promise);

// Promise {<fulfilled>: undefined}

Rejected(실패): Promise에서 reject를 실행하면 Rejected(실패) 상태가 됩니다.

const promise = new Promise((resolve, reject) => {
	reject();
});

console.log(promise);

//Promise {<rejected>: undefined}

Producer: Promise를 처음 생성할때 Promise의 내부 코드블럭이 실행됩니다. 이를 executor라 하는데, executor 실행 결과에 따라 resolve 혹은 reject를 불러줍니다.

const isReady = true;
// 1. Producer
const promise = new Promise((resolve, reject) => {
	// executor
  console.log("Promise is created!");
  if (isReady) {
    resolve("It's ready");
  } else {
    reject("Not ready");
  }
});

// Promise is created!

Consumer: Promise의 결과에 따라 후처리를 하는 부분입니다. Promise가 정상적으로 실행되어 resolve가 되었으면 then을 통해 후처리가 가능하고, reject가 될 경우 catch를 통해 후처리가 가능합니다.

const isReady = true;
// 1. Producer
const promise = new Promise((resolve, reject) => {
  console.log("Promise is created!");
  if (isReady) {
    resolve("It's ready");
  } else {
    reject("Not ready");
  }
});

// 2. Consumer
promise
	// promise에서 resolve가 될경우
  .then(messsage => {
    console.log(messsage);
  })
	// promise에서 reject가 될경우
  .catch(error => {
    console.error(error);
  })

// Promise is created!
// It's ready

await를 사용하면 promise가 처리될 때까지 기다리게 된다. 결과는 그 이후 반환되며 promise.then 보다 좀 더 세련되게 프라미스의 result 값을 얻을 수 있도록 해주는 문법이다. promise.then 보다 가독성도 좋고 쓰기도 쉽다.

async function showAvatar() {

  // JSON 읽기
  let response = await fetch('/article/promise-chaining/user.json');
  let user = await response.json();

  // github 사용자 정보 읽기
  let githubResponse = await fetch(`https://api.github.com/users/${user.name}`);
  let githubUser = await githubResponse.json();

  // 아바타 보여주기
  let img = document.createElement('img');
  img.src = githubUser.avatar_url;
  img.className = "promise-avatar-example";
  document.body.append(img);

  // 3초 대기
  await new Promise((resolve, reject) => setTimeout(resolve, 3000));

  img.remove();

  return githubUser;
}

showAvatar();

Express.

Nods.js로 서버구현을 하기 위해 Express라는 웹 프레임 워크를 사용하였다.
터미널에서

$ npm init -y

을 쳐서 package.json을 생성한다

$ npm install express

그 후 express를 설치하였다.

내일부터는 Express를 이용한 서버구현에 들어갈 것 같다... 기대된다 ㅎㅎ

 

돌아온 알고리즘의 시간...

홀수 문제
7개의 자연수가 주어질 때, 이들 중 홀수인 자연수들을 모두 골라 그 합을 구하고, 고른 홀수들 중 최소값을 찾는 프로그램을 작성하라

function OddControl(arr){
    let newarray = []
    sum = 0
    Min = 0
    
    for(let abc of arr){
        if (abc % 2 == 1){
            sum += abc
            newarray.push(abc)
        }
    }
    Min = Math.min(...newarray)
    
    return `합은 : ${sum}, 최소값은 : ${Min}`

}
let arr = [12,77,38,41,53,92,85]
console.log(OddControl(arr))

 

'Today I Learned' 카테고리의 다른 글

7 TIL  (0) 2021.09.23
6 TIL  (0) 2021.09.23
3 TIL & WIL  (0) 2021.09.19
2 TIL  (0) 2021.09.19
1 TIL  (1) 2021.09.17

항해 1주차가 끝났다. 

정말 뜻 깊은 경험이었다.
생에 첫 협업 프로젝트  처음엔 불편하고 어색했지만 조원분들 다 너무 좋아서 프로젝트도 순조롭게 진행됐던 거 같다.
다음 프로젝트 때는 더 발전된 내가 되어야겠다.

주특기를 node.js로 하였고 그래서 자바스크립트 왕기초 문법 공부를 했다.


const 변수이름 = 값

const는 let과 달리 변수에 값을 재할당할 필요가 없을 때 쓴다. 해당 변수가 고정된 값을 계속 갖고 있을 때 쓰면 좋다.

 

데이터타입.

console.log('My' + ' car') // My car를 출력
console.log('1' + 2) // 12를 출력

'1' +2 는 string '12' 를 출력하게 된다.

console.log(2 + 1) // 3을 출력
console.log(2 - 1) // 1을 출력
console.log(4 / 2) // 2를 출력
console.log(2 * 3) // 6을 출력
console.log(10 % 3) // 나머지(remainder) 연산자. 1을 출력
console.log(10 ** 2) // exponentiation. 10의 2승인 100을 출력

 

증감연산자.

let count = 1
const preIncrement = ++count
// 증감연산자를 앞에 놓게 되면 아래 주석으로 처리한 두 줄의 코드와 같은 내용입니다.
// 먼저 자기 자신에게 1을 더해서 재할당 한 후, 이를 preIncrement 에 할당했다는 의미입니다.
// count = count + 1
// const preIncrement = count
console.log(`count: ${count}, preIncrement: ${preIncrement}`) // count: 2, preIncrement: 2
let count = 1
const postIncrement = count++
// 증감연산자를 뒤에 놓게 되면 아래 주석으로 처리한 두 줄의 코드와 같은 내용입니다.
// postIncrement에 자기 자신의 값을 먼저 할당하고, 이후에 1을 더해서 재할당합니다. 
// const postIncrement = count
// count = count + 1
console.log(`count: ${count}, postIncrement: ${postIncrement}`) // count: 2, postIncrement: 1

 

대입연산자.

const shirtsPrice = 100000
const pantsPrice = 80000
let totalPrice = 0

totalPrice += shirtsPrice // totalPrice = totalPrice + shirtsPrice 와 동일
console.log(totalPrice)
totalPrice += pantsPrice // totalPrice = totalPrice + pantsPrice 와 동일 
console.log(totalPrice)

totalPrice -= shirtsPrice // totalPrice = totalPrice - shirtsPrice 와 동일
console.log(totalPrice)

 

일치연산자.

console.log(1 === "1") // false를 출력
console.log(1 == "1" // true를 출력

 

논리연산자.

let isOnSale = true
let isDiscountItem = true

console.log(isOnSale && isDiscountItem) // true && true 이므로 true
console.log(isOnSale || isDiscountItem) // true || true 이므로 true

isOnSale = false
console.log(isOnSale && isDiscountItem) // false && true 이므로 false
console.log(isOnSale || isDiscountItem) // false || true 이므로 true

isDiscountItem = false
console.log(isOnSale && isDiscountItem) // false && false 이므로 false
console.log(isOnSale || isDiscountItem) // false || false 이므로 false

console.log(!isOnSale) // !false 이므로 true

 

if 문.

const shoesPrice = 40000
if (shoesPrice < 50000) { // 신발 가격이 50000원보다 작으므로 해당 코드가 실행됨
	console.log('신발을 사겠습니다.')
}

const capPrice = 50000
if (capPrice < 50000) {
	console.log('모자를 사지 않겠습니다.') // 모자 가격이 50000원보다 작지 않으므로 해당 코드가 실행되지 않음
}

 

if else.

const shoesPrice = 50000
if (shoesPrice < 40000) { 
	console.log('신발을 사겠습니다.')
} else if (shoesPrice <= 50000) {
	console.log('고민을 해볼게요...')  // 신발 가격이 50000원보다 작거나 같으므로 않으므로 해당 코드가 실행됨
} else {
	console.log('너무 비싸요. 신발을 사지 않겠습니다.')
}

 

while.

let temperature = 20
while (temperature < 25) {
	console.log(`${temperature}도 정도면 적당한 온도입니다.`)
    temperature++ // 증감연산자를 활용해 온도 변화시킴
}

반복문의 조건이 계속해서 true 를 리턴한다면 무한루프에 빠져서 프로그램이 끝나지 않는다. 주의!

 

for.

for (let temperature = 20; temperature < 25; temperature++) {
	console.log(`${temperature}도 정도면 적당한 온도입니다.`)
}

for, if.

for (let number = 1; number <= 10; number++) {
	if (number % 3 === 0) {
		console.log(`${number}는 3으로 나눠서 떨어지는 숫자입니다.`)
	}
}

 

함수 선언 호출.

function 함수명(매개변수들...) {
이 함수에서 실행할 코드들
return 반환값
}

const 변수명 = 선언한 함수명(매개변수들...)

Class선언.

class Notebook {
	constructor(name, price, company) {
		this.name = name
		this.price = price
		this.company = company
	}
}

 

class 키워드와 클래스명
class는 클래스를 선언하는 문구이고 그 뒤에 바로 클래스 명이 나옵니다. 클래스명도 마치 변수명처럼 내가 표현하고자 하는 데이터를 잘 나타낼 수 있는 이름이 좋다. 위의 예에서 Notebook 대신 Person 같은 이름을 쓴다면 다른 사람들이 코드를 봤을 때 이상하다고 생각할 것이다.

생성자
중괄호 안에는 생성자라는 것을 적어줍니다. 혹시 생성자가 함수와 많이 비슷하다. 이 생성자는 말 그대로 나중에 객체가 '생성'이 될 때 자바스크립트 내부에서 호출이 되는 함수라고 생각하면 된다. 생성자를 좀 더 살펴보면 3개의 매개변수를 정의했고 각각의 이름은 name, price, company 이다.

생성자의 바디를 보면 this 라는 키워드가 등장한다 이 this는 클래스를 사용해 만들어질 객체 자기 자신을 의미하고 this 뒤에 붙는 name, price, company는 객체의 속성이다. 생성자의 바디에서는 함수 호출시 전달할 매개변수 name, price, compay를 객체의 속성 name, price, company에 각각 할당하고 있는 것이다.

 

메소드 method.

// 클래스 선언
class Product {
	constructor(name, price) {
		this.name = name
		this.price = price
	}

	printInfo() {
		console.log(`상품명: ${this.name}, 가격: ${this.price}원`)
	}
}

// 객체 생성 및 메소드 호출
const notebook = new Product('Apple Macbook', 2000000)
notebook.printInfo() // 상품명: Apple Macbook, 가격: 2000000원

 

객체 리터럴(Object Literal).
자바스크립트에서는 객체 리터럴을 활용해서 바로 객체를 만들 수도 있다. 객체 리터럴은 크랠스와 같은 템플릿 없이 빠르게 객체를 만들 수 있는 방법이라고 생각하면 된다. 2개 이상의 속성과 메소드가 있을대는 쉼표로 구별해주고 가독성을 위해서 줄바꿈도 해주는게 좋다.

const 변수명 = {
속성명: 데이터,
메소드명: function () { 메소드 호출시 실행할 코드들 }
}

const computer = {
	name: 'Apple Macbook',
	price: 20000,
	printInfo: function () {
		console.log(`상품명: ${this.name}, 가격: ${this.price}원`)
	}
}

computer.printInfo()

name, price라는 속성과 printInfo 라는 메소드를 가지고 있는 객체를 만들어서 computer라는 변수에 할당하는 코드이다. 해당 객체의 printInfo 메소드를 바로 호출까지 하였다.
결과적으로는 클래스를 활용해 객체를 만든 것과 동일하다. 그렇다면 왜 굳이 복잡하게 클래스를 정의할까? 바로 재사용성 때문이다. 한번 클래스를 만들어두면 같은 속성과 메소드를 갖고 있는 객체를 훨씬 더 간결한 코드로 만들 수 있다.
Ex)
의류 쇼핑몰을 만들려고 한다. 옷의 종류는 많지만 기본적으로 색깔, 싸이즈, 가격의 속성을 가지고 있다. 그리고 이 옷들의 세 속성을 바로 확인할 수 있게 출력해주는 메소드가 필요하다. 클래스와 객체를 활용해 작성해보자.

class Cloth {
    constructor(color, size, price) {
        this.color = color
        this.size = size
        this.price = price
    }

    printInfo() {
        console.log(`색깔: ${this.color}, 사이즈: ${this.size}, 가격: ${this.price}`)
    }
}

const shirts = new Cloth('white','M','50000')
const coat = new Cloth('navy', 'L', '200000')

shirts.printInfo()
coat.printInfo()

솔직히 앞에 있던 건 다 한번씩 훑어보면 됐지만 클래스는 다르다 여러 번 반복해서 써보고 익혀야한다.!!!!!!!!!

배열의 선언.

// 1번째 방법
const arr1 = new Array(1, 2, 3, 4, 5)

// 2번째 방법
const arr2 = [1, 2, 3, 4, 5]

반복문으로 배열 불러오기

const rainbowColors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']

for (let i = 0; i < rainbowColors.length; i++) {
	console.log(rainbowColors[i])
const rainbowColors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']

for (const color of rainbowColors) {
	console.log(color)
}

열 개 데이터 가진 배열로 가격 합계와 평균 구하기

const priceList = [1000, 2000, 5000, 7000, 10000, 9000, 3000, 15000, 20000, 17000]
let sum = 0

for (const price of priceList) {
	sum += price
}

const avg = sum / priceList.length
console.log(`합계: ${sum}, 평균: ${avg}`)

 

JWT (JSON Web Token) 이란?
JSON 웹 토큰은 말그대로 JSON 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 web Token을 의미한다. JWT는 Token 자체를 정보로 사용하는 Self-Contained 방식으로 정보를 안전하게 전달한다. 주로 사용자 인증이나 정보 전달에 사용된다. JWT를 이용하면 Client는 자신의 정보를 보는 것은 가능하지만 수정은 불가능하다. 그 데이터를 수정하려면 반드시 Server를 통해서만 가능하다.

  • 예를 들어, 로그인 기능을 생각해보면 사용자가 로그인하면 서버에서 회원임을 인증하는 토큰을 넘겨줌으로써 이후 회원만 접근할 수 있는 서비스 영역에서 신분을 확인하는 데 쓰일 수 있습니다.

[IT정보] JSON 웹 토큰(JSON Web.. : 네이버블로그 (naver.com)

 

[IT정보] JSON 웹 토큰(JSON Web Token, JWT) 개념

JSON 웹 토큰(JSON Web Token, JWT)이란? JSON 웹 토큰(JSON Web Token, JWT)은...

blog.naver.com

API란 무엇일까? API 쉽게 이해하기 (brunch.co.kr)

 

API란 무엇일까? API 쉽게 이해하기

API | API, 쉽게 이해하기 API란? “API(Application Programming Interface, 응용 프로그램 프로그래밍 인터페이스)는 응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을

brunch.co.kr

API는 응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다.

[JAVA] 자바 인터페이스란?(Interface)_이 글 하나로 박살내자 (tistory.com)

 

[JAVA] 자바 인터페이스란?(Interface)_이 글 하나로 박살내자

1. 인터페이스 개념과 역할 인터페이스....이 글하나로 박살내자. (회사에서 존댓말을 많이 쓰기때문에 여기서라도 반말로 글을 써보고 싶음 ㅎ) 인터페이스는 뭘까?? 결론부터 말하면, 극단적으

limkydev.tistory.com

이건 인터페이스의 기본 알아두자!!!

이번 프로젝트에서는  파이썬부분(백)에서 디비불러와서 프론트로 GET POST하며 JSON형태로 값을 주고 받았다. 그것도 api일종이긴 한데 너무 기본적인거라고 한다.ㅎ ㅎ 넘 어렵쓰;

내일부터 주특기 강의가 열린다.
후... 노드js.... 이놈 딱 대!

앗 깜박하고 알고리즘 안올렸다;; 새벽에 일어나서 올림
연필 1다스는 12자루 학생 1인당 1자루씩 나누어준다고 할 때 N명의 학생수를 입력하면 필요한 연필의 다스 수를 계산하는 프로그램 짜시오.
넘 쉽다. 그냥 12로 나누어서 몫 나머지 구하는 함수 쓰면 되기도 하고
아에 함수 Math.ceil() 쓰면 바로 가능하다

function solution(n){
    let answer = Math.ceil(2.111)
    return answer
}
console.log(solution(25))

너무 쉬워서 하나 더
1에서 n까지의 합을 출력하는 프로그램 작성

function solution(n){
    let answer=0;
    for (i = 1; i<=n; i++){
        answer=answer+i
    }
    return answer
}
console.log(solution(6))

빨리 쉬운 문제들 넘기기 위해서 하나 더
7개의 수가 주어지면 그 숫자 중 가장 작은 수를 출력하는 프로그램

function solution(arr){
    let answer;
    // let min = Number.MAX_SAFE_INTEGER
    let min=arr[0];
    for (let i=1; i<arr.length; i++){
        if(arr[i]<min) min=arr[i]
    }
    answer=min
    return answer

}

 

'Today I Learned' 카테고리의 다른 글

7 TIL  (0) 2021.09.23
6 TIL  (0) 2021.09.23
4 TIL 항해 8일차  (0) 2021.09.20
2 TIL  (0) 2021.09.19
1 TIL  (1) 2021.09.17

+ Recent posts