즉, 위 코드는 express, MongoDB, multer, path 모듈을 초기화하고 해당 모듈들을 사용할 수 있도록 준비하는 역할을 한다.
요즘 공부하고 있는 모듈인 express 에 관하여 좀 적어보자면…
express 모듈 불러오기
const app = express();
이는 express 에플리케이션을 생성하는 코드
http 요청과 응답을 처리하고 라우팅, 미들웨어, 템플릿 엔진 등을 제공한다.
express() 는 express 애플리케이션 객체를 반환하는 함수이다. 이를 app 변수에 할당하여 애플리케이션 객체를 참조할 수 있도록 한다.
app 객체를 활용하여 서버의 동작을 정의하고 미들웨어를 추가하며, 라우팅을 설정할 수 있다
즉, const app = express(); 코드는 express 애플리케이션을 초기화하고 해당 애플리케이션의 객체에 대한 참조를 app 변수에 저장하는 역할을 한다.
이후 app 객체를 통해 서버의 동작을 설정하고 요청에 대한 응답을 처리할 수 있다
express란?
express는 Node.js로 작성된 웹 프레임워크이며, const app = express(); 코드는 express 애플리케이션을 초기화하고 해당 애플리케이션의 객체에 대한 참조를 app 변수에 저장하는 역할을 한다. 이후 app 객체를 통해 서버의 동작을 설정하고 요청에 대한 응답을 처리할 수 있다.
아래는 express를 사용한 간단한 예시 코드이다.
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello, World!');
});
app.listen(3000, () => {
console.log('Server started on port 3000');
});
위 코드에서 app.get은 라우팅을 설정하는 메서드로, '/' 경로로 GET 요청이 왔을 때 'Hello, World!' 문자열을 응답으로 보내주는 코드이다. app.listen은 서버를 실행시키는 메서드로, 3000번 포트로 서버를 시작한다.
2. 몽고디비 연결과 변수 설정하기
const client = new MongoClient('mongodb+srv://sparta:패스워드칸@sparta.rqx1qlk.mongodb.net/?retryWrites=true&w=majority');
let db;
위 코드를 해석해보겠다.
해당 코드는 MongoDB 서버와 연결하는 역할을 한다.
MongoClient는 MongoDB 클라이언트를 초기화하는 코드이며, 이 코드에서는 MongoDB Atlas를 사용하고 있다.
new MongoClient()를 호출하여 몽고DB에 연결하여 client 변수에 저장한다.
패스워드칸에는 사용자의 실제 패스워드를 입력해야 한다.내 db를 연결할때는 내 비밀번호를 사용하였다
이 패스워드를 사용하여 sparta 데이터베이스에 연결한 후에는 db 변수를 선언하여, 나중에 데이터베이스에서 데이터를 조회 및 조작할 때 사용할 수 있도록 한다.
db변수
db 변수는 몽고디비 연결 후에 클라이언트의 db() 메서드를 사용하여 데이터베이스에 접근하는데 사용된다.
에를 들어
db.collection(collectionname')
형식으로 접근하고 쿼리를 실행할 수 있다.
데이터베이스 연겷이 성공하면 databaseConnect() 함수가 호출되고, client.cd('dbsparta) 코드를 통해 ‘dbspartq’이름의 데이터베이스에 연결된 db 변수에 데이터베이스 클라이언트가 연결된다,
이를 사용하여 데이터베이스 조작을 수행할 수있다.
즉, db 변수는 MongoDB 데이터베이스 클라이언트에 액세스하고 조작하는데 사용되는 중요한 변수이다
3. 몽고디비 데이터베이스에 연결하고 연결 상태 확인
async function databaseConnect() {
try {
await client.connect();
db = client.db('dbsparta');
console.log('MongoDB에 연결되었습니다.');
} catch (error) {
console.error('MongoDB 연결 오류:', error);
}
}
위 코드의 내용을 설명해보자면,
databaseConnect() 함수는 비동기 함수로 선언되어 있다.
함수 내부에서는 await client.connect(); 코드를 사용하여 client 객체가 MongoDB에 연결될 때까지 대기한다.
연결이 성공하면 client.db('dbsparta') 코드를 사용하여 'dbsparta'라는 이름의 데이터베이스에 대한 클라이언트 객체를 얻으며, 이 클라이언트 객체는 db 변수에 할당된다.
연결이 성공하면 **'MongoDB에 연결되었습니다.'*라는 메시지가 콘솔에 출력된다.
연결 중에 오류가 발생하면 catch 블록이 실행되고, 오류 메시지가 **'MongoDB 연결 오류:'*와 함께 콘솔에 출력된다.
await client.connect()
await client.connect()는 MongoDB 클라이언트가 MongoDB 서버에 연결하는 비동기 함수이다. 이 함수는 await 키워드를 사용하여 연결이 완료될 때까지 기다리고, 성공하면 클라이언트 객체를 반환한다. 이 객체는 이후 데이터베이스와의 상호 작용을 위해 사용된다.
위 코드에서 await MongoClient.connect()는 MongoDB 클라이언트가 MongoDB 서버에 연결하는 비동기 함수이다. url은 MongoDB 서버의 URL 주소를 나타내고, dbName은 연결하려는 데이터베이스의 이름이다. 연결이 성공하면 클라이언트 객체가 반환되며, 이 객체를 사용하여 데이터베이스와 상호 작용할 수 있다.
**db.collection('fan').find({}, { projection: { _id: 0 } })**를 사용하여 'fan' 컬렉션의 모든 문서를 조회함. **{ projection: { _id: 0 } }**는 결과에서 _id 필드를 제외하고 조회하도록 지정한 것
toArray() 메서드를 사용하여 조회된 결과를 배열로 변환
Promise 체인을 이용하여 조회된 결과인 **allComments**를 처리합니다. then 블록에서는 각 댓글의 photo 필드가 존재하는 경우, 해당 경로를 조합하여 절대 URL로 변경함. 이는 클라이언트에서 댓글의 이미지를 로드할 수 있도록 함
응답에 Cache-Control 헤더를 설정하여 캐시를 사용하지 않도록 지정함
**res.json({ result: allComments })**를 사용하여 JSON 형태로 **{ result: allComments }**를 응답 이는 클라이언트에게 조회된 댓글 목록을 전달
조회나 처리 중에 오류가 발생한 경우, catch 블록에서 오류를 콘솔에 기록하고 클라이언트에게 상태 코드 500과 JSON 응답으로 **{ msg: '서버 오류' }**를 전송
위의 코드는 /guestbook 경로로 GET 요청이 들어오면 MongoDB에서 'fan' 컬렉션의 댓글을 조회하여 클라이언트에게 응답하는 역할을 한다. 이를 통해 게시판의 댓글 목록을 클라이언트로 전달한다.
npm: the ubiquitous pakage manager for Node packages
→ how we’ll get and install Express
HOW to get install npm
To get and install Express using npm, open a terminal and type npm install express. This will download the latest version of Express and install it in your project's node_modules
in the wry tradition of PHP, GNU , WINE and others, “npm” is not an acronym ; rather, it is a recursive abbreviation for npm is not an acronym.
broadly speaking, a package managers’s two primiary responsibilities are instaling packages and manging dependencies. npm is a fast, capacle, and painless package manager
which i feel is in large part responsible for the rapid growth and diversity of the Node ecosystem.
when does npm installed?
is installed when you install Node, so if you downloaded the node, you may got it
The primary command we use is npm , which means install
for example , to install Grunt (a popular Javascript task runner), you would issue the following command -
npm install -g grunt-cli
the -g flage tells npm to install the package globally
globally
it’s available globally on the system, anywhere
this distinction will become clrearer when we cover the package.json files. For now, the rule of thumb is that Javascript utilities (like Grunt) will generally be installed globally. whereas packages that are specific to your web app o project will not
💡 unlike languages like python- which underwent a major language change from 2.0 to 3.0, necessitating a way to easily swithch between different environments. - the node platform is new enough that it is. however, if you do find yourself needing to support multiple- version of node, there is a project, nvm that allows you to switch environments
let’s see the two ways how npm works
local
if i don't choose other specific options, the package will be installed in local.
node_modules directory will be created in project root and the package will be installed in it.
local-installed packages can be only used in specific project
npm install <packagename>
global
if you wanna install package in global way, you can put -g option.
it will install in global ways and it would make you to use that package on everywhere.
npm install -g <packagename>
for more, global-installed pacakage’sdownload place will be different depending on your os.
If you install the package in global way, it can be more comfortable to use it. but the fatal thing of this is : their info would not be written at package.json
for this, we can use -D option and install it devdependencies, and run it by npx command.
npm install -D nodemon
npm nodemon <packagename>
if you need some, there’s an analogy for you :
Development Team Leader: Controls the work efficiency of the development team and directs work to general employees.
Employee: A worker who is very diligent in whatever he is asked to do (?)
[ Scenario 1 ]
The development team leader instructs each of the three employees at the same time. ( = asynchronous )
Surprisingly, the development team leader doesn't even check what he ordered the 3 employees to do, and does his own work (= asynchronous)
Each employee completes the assigned task on their own and reports to the development team leader. ( = non-blocking )
[ Scenario 2 ]
The development team leader instructs employee 1 to work.
And until the work of employee 1 is over, it gives an eye to when it is over. ( = motive )
Employee 1's work is too slow, so he tries to give the job to another employee. ( = asynchronous )
However, employee 1 grabs the hem of the development team leader’s clothes asking for help. ( = blocking )
Employee 2 and Employee 3 who watch it are willing to work hard no matter what they are given, but there is no work. ( = motive )
var answer = [];
while(answer.length < 3){
var randomNum = Math.floor(Math.random()*10);
if(answer.indexOf(randomNum) > -1) continue;
answer.push(randomNum);
}
위 코드에서는 랜덤으로 숫자를 생성해 생성된 숫자가 4개 미만이라면 새로운 숫자가 생성되고,
중복되지 않는다고 하면 결괏값인 randomNum 에 저장이 된다.
조금 더 자세히 알아보도록 하자
생성되는 숫자 제어하기
while(answer.length < 3){
만약의 answer 배열의 길이가 3보다 작다면 ~ 으로 시작해서 작동하는 코드이다.
answer 배열의 길이가 3개 이상이라면 멈추게 된다
숫자를 정수화한 후 Randomnum에 넣기
var randomNum = Math.floor(Math.random()*10);
이때 math.random()으로 숫자를 생성하고,
이 숫자의 범위는 0~1이기 때문에 *10을 해줘서 1~10으로 바꿔준다.
그 후 Math.floor로 소숫점을 떨궈주고, randomNum으로 정의해준다.
코드의 중복 확인하기
if(answer.indexOf(randomNum) > -1) continue;
indexof: 지정된 요소의 인덱스를 검색하는 javascript의 내장 메서드이다.
호출한 배열에서 첫번째로 일치하는 요소의 인덱스변환, 일치하는 요소가 없는 경우 -1 을 반환한다.
만약 2번째 숫자가 같았으면 해당숫자의 인덱스인 1이 반환되고,
첫번째 숫자가 같았으면 해당 숫자의 인덱스인 0이 반환된다.
-1보다 작으면 continue로 계속해준다
indexof도 곧 포스팅할 예정이다!.
중복이 아니라면
answer.push(randomNum);
randomNum에 answer가 들어가게 된다
4. 세자리 숫자 입력받고 사용자 입력의 중복/글자수 이상 처리하기
function playGame() {
readline.question('세자리 숫자를 입력하세요.', (playerInput) => {
count++;
if(playerInput.length !== 3 || new Set(playerInput).size !== 3){
console.log("세자리의 서로 다른 숫자를 입력하세요.");
playGame();
return;
}
readline를 이용하여 세자리 숫자를 입력받았다.
그러나 만약 세 자리 숫자 안에 중복된 숫자가 있거나, 4자리라면 어떻게 되는 걸까?
당연히 프로그램 진행에 문제가 생긴다.
자세히 뜯어보자.
세 자리 숫자 입력받고 입력받을 때 마다 시도횟수 하나씩 증가시키기
function playGame() {
readline.question('세자리 숫자를 입력하세요.', (playerInput) => {
count++;
나는 playGame이라는 함수를 사용하기로 했다
제일 먼저 readline.question으로 사용자의 입력을 받았다
실행 결과의 이 부분이라고 생각하면 될 것 같다.
사용자가 입력한 값은 콜백 함수의 매개변수인 playerInput에 저장된다.
한번 입력을 받을 때 마다 count 횟수를 1씩 늘려준다
이는 마지막에 시도 횟수를 출력할때 사용된다
사용자 입력의 중복이 있거나 길이가 3이 아니라면
if(playerInput.length !== 3 || new Set(playerInput).size !== 3){
console.log("세자리의 서로 다른 숫자를 입력하세요.");
playGame();
return;
}
논리 OR 연산자
두 개의 피연산자중 하나 이상이 True이상인지를 확인하고, 결과로 True를 반환한다.
왼쪽 피연산자를 평가한 결과가 True이면 오른쪽 피연산자 평가 x 그냥 바로 True반한
왼쪽 피연산자를 평가한 결과가 False 이면 오른쪽 피연산자 평가하고 그 결과를 반환함
(추후 포스팅해볼 내용이 더 늘어나버렸네…;;
이걸 어떻게 적용했냐면
if(playerInput.length !== 3 || new Set(playerInput).size !== 3){
이 상황에서 playerInput.length이 3이 아니라면, 뒤에 중복 여부 결과는 보지 않고 바로 True를 반환한다.
숫자가 3개도 아닌데 굳이 중복 볼 필요가 있냐는거다.
그래서 먼저 앞의 숫자 갯수를 확인해본 후 playerInput을 Set 형태로 바꿔준다
*set은 중복이 존재할 수 없다
중복이 없는 상태에서 숫자의 갯수가 3개가 맞는지 확인하는 과정이였다.
논리 OR 연산자 쓰는 게 습관이 되어가고 있다 ! &ㅠ&
5. 기본 값 세팅하기
var strike = 0;
var ball = 0;
var checkResult = Array(3).fill(0);
strike 카운트와 Ball 카운트를 초기화해준다.
그리고 Array(3).fill(0)이라는 게 보이는데 이는 길이간 3인 배열을 생성하고, 그 배열의 모든 요소를 0으로 채우는 역할을 한다.
Array 생성자 함수에 문자 3을 인수로 넣어 배열의 길이를 설정하고, fill 메서드를 조합해서 쓰여진다.
나는 이것을 세 자리 수에 각각 비교하도록 구성해보려 하였다.
array와 Fill을 사용하지 않고 작성한다면??
직접 배열 리터럴을 사용하여 배열을 생성하고 요소에 초기값을 할당한다
var checkResult = [0, 0, 0];
배열 생성 후에 반복문이나 인덱스 접근을 통해 각 요소에 초기값을 할당한다.
var checkResult = [];
for (var i = 0; i < 3; i++) {
arr[i] = 0;
}
빈 배열을 생성한 후에 반복문을 사용하여 각 요소에 초기값 0을 할당하는 법.
배열의 크기가 커지면 이 방향을 사용하여야 할듯
away.from 메서드를 사용하여 배열을 생성하고 초기값을 할당한다
var arr = Array.from({ length: 3 }, () => 0);
이러한 방법으로도 쓸 수 있다. array.fill이랑 다른 점이라면 여러 개의 매개변수를 받을 수 있다 정도?