Node.js

Node.js - 수업 1일차

kakaroo 2022. 8. 22. 10:36
반응형

 

1. 웹 서버 구동위한 준비 -  (구름 IDE)

 

서버 구동

python3 -m http.server

 

서버 실행 URL과 포트 지정

 

URL 이동

 

2. Node.js 를 하기 위한 기본적인 문법

 

<Variable>

<!DOCTYPE HTML>

<html>
	<head>
		<meta charset="utf-8">
	</head>	
	<body>
		<h1>1 variable </h1>
		<script>
			//브라우저의 개발자 도구에서 console 탭을 확인해 주세요
			//console.log("hello, world");
			
			//스코프(scope): 참조대상 식별자(identifier, 변수나 함수의 이름)을 찾아내기 위한 규칙
			//-> 어떤 이름을 참조하기 위해 사용할 수 있는 유효 범위
			
			//스코프의 종류
			//1. 전역 스코프: 코드 어디에서든지 참조할 수 있음
			//2. 지역 스코프 또는 함수 레벨 스코프: 함수 코드 블럭이 만든 스코프로 함수자신과
			//									하위 함수에서만 참조할 수 있음
			//3. 블럭 레벨 스코프: 중괄호를 사용한 스코프로 주로 제어문에 사용함
			
			//전역스코프 : 함수 외부 영역
			
			function foo() {
				//지역 스코프 또는 함수 레벨 스코프
			}
			if(true) {
				//블록 레벨 스코프
			}
		</script>
		<script>
			//모든 변수는 선언된 위치에 따라서 크게 2가지로 나뉠수 있다
			//1. 전역변수: 전역 스코프에서 선언된 변수로 어디에서나 참조할 수 있음
			//2. 지역변수: 지역 스코프에서 선언된 변수로 그 지역과 그 지역 하위지역에서만 참조할 수 있음
			var global = "global";	//전역변수
			
			function bar() {
				console.log(global);
				
				var local = "local"
				console.log(local);
			}
			
			bar();
			//console.log(local);	//오류
			
			if(true) {
			   //블럭 레벨 스코프
				//자바 스크립트는 기본적으로 블럭레벨 스코프를 지원하지 않으므로 아래의 변수는
				//전역 변수로 해석됩니다.
				var test = "test"
			}			
			console.log(test);	//문제없이 동작함
		</script>
	</body>
		
</html>

 

 

<!DOCTYPE HTML>

<html>
	<head>
		<meta charset="utf-8">
	</head>	
	<body>
		<h1>2 variable </h1>
		<script>
			//var 키워드
			var x = "X";
			console.log(x);
			
			y= "Y";		//var 키워드가 없다. 안 써도 되는거 아니냐? 왜 쓰는지 알아보자
			console.log(y);
			
			function foo() {
				//지역 스코프에서 var 키워드를 사용하여 변수를 선언하면
				//해당 변수는 지역 스코프의 특성을 갖는다
				var z = "Z";
			}
			foo();
			//console.log(z);	//오류
			
			function bar() {
				//지역 스코프에서 var 키워드를 사용하지 않고 변수를 선언하면
				//해당 변수는 전역 스코프의 특성을 갖는다
				a = "A";
			}
			bar();
			console.log(a);	//된다
		</script>
	</body>
		
</html>

 

<!DOCTYPE HTML>

<html>
	<head>
		<meta charset="utf-8">
	</head>	
	<body>
		<h1>3 variable </h1>
		<script>
			var age = 20;
			console.log(age);
			
			//변수를 다시 선언할 수 있다.
			var age = 30;
			console.log(age);
			
			//스크립트 언어는 인터프리터 언어로 라인단위로 읽어서 실행한다
			//하지만, 자바스크립트는 생성된 변수나 함수등을 먼저 추출해서
			//해석기 내의 메모리에 로딩한 뒤(호이스팅:끌어올림), 코드를 실행한다.
			//그렇기 때문에 아래 코드는 에러가 발생하지 않는다.
			//초기화 된 값은 호이스팅하지는 않고 변수가 선언된 것만 로딩한다.
			console.log(uname);	//undefined 로 출력됨
			var uname = "daniel";
			console.log("------------------------------");
		</script>
		<script>
			var n = 1;
			function test() {
				//지역 스코프에서 선언된 변수가 없으면 전역변수에서 찾는다.
				//함수 레벨 안에서 아래 변수로 선언되었기 때문에 호이스팅되어 버린다.
				console.log(n);	//undefined
				
				var n = 2;
				console.log(n);	//2
			}
			test();
			console.log("------------------------------");
		</script>
		<script>
			//let 키워드는 var 키워드의 문제를 해결하기 위해 ES6에서 추가됨
			var temp1;	//선언만 가능
			let temp2;	//변수 선언이 가능
			
			var temp3 = 20;
			let temp4 = 20;	//변수를 선언과 동시에 초기화가 가능
			
			var temp3 = 30;	//var 키워드는 중복선언이 가능하다
			//let temp4 = 30; //오류! 중복선언이 불가능하다.
			
			//console.log(temp5);	//오류! 호이스팅은 되지만 초기화가 안 되었다고 에러발생시킴
			let temp5 = 10;
			console.log("------------------------------");
		</script>
		<script>
			if(true) {
				var v = "var";
				let l = "let";
			}
			console.log(v);
			//console.log(l);	//오류! let으로 선언된 변수는 블럭 레벨 스코를 갖는다.
			
			for( var i=0; false; ) {}
			console.log(i);	//ok
			
			for( let j=0; false; ) {}
			console.log(j);	//오류! let으로 선언된 변수는 블럭 레벨 스코를 갖는다.
		</script>
	</body>
		
</html>

 

<!DOCTYPE HTML>

<html>
	<head>
		<meta charset="utf-8">
	</head>	
	<body>
		<h1>4 variable </h1>
		<script>
			let r = 2;			
			console.log(r ** 2 * 3.14);	//하드코딩
			//let pi = 3.14;
			//console.log(r ** 2 * pi);	//심볼,, 하지만 이건 값을 변경할 수 있다.
			const pi = 3.14;
			console.log(r ** 2 * pi);	//심볼
			
		</script>
		<script>
			//리터럴(literal): 그 자체가 값을 의미하는 것
			10, 3.14, "hello", true;
			
			//변수
			let data;
			data = 10;
			data = 3.14;
			data = "hello";
			data = true;
			
			//상수(const variable)
			const PI = 3.14;
			//PI = 0;	//오류!
		</script>
	</body>
		
</html>

 

 

<Function>

 

<!DOCTYPE HTML>

<html>
	<head>
		<meta charset="utf-8">
	</head>	
	<body>
		<h1>5 function </h1>
		<script>
			//1급 시민(first class citizen)
			//1. 변수에 할당될 수 있다
			//2. 인자(argument)로 전달될 수 있다.
			//3. 함수로부터 반환될 수 있다.
			// ex)리터럴
			//let age = 20;
			
			//자바스크립트에서는 함수도 1급 시민이다. 추가적으로 다음의 조건을 요구하는 경우도 있다.
			//런타임에 생성할 수 있다.
			//익명으로 생성할 수 있다.
			
			//자바스크립트는 위의 추가적인 요건을 만족한다. 이처럼 1급 시민의 조건을 만족하는 함수를
			//일급함수(first class function)이라고 한다.
		</script>
		<script>
			//1. 변수에 할당할 수 있다.
			function print_hello() { console.log("hello");}
			const fn = print_hello;
			fn();
			
			//2. 함수의 인자로 전달할 수 있다.
			function sayHello() { return "hello, "; }
			function greeting(helloMessage, name) {
				console.log(helloMessage() + name)
			}
			greeting(sayHello, "kakaroo");
			
			//3. 함수로부터 반환될 수 있다.
			function return_print_hello() { return print_hello; }
			return_print_hello()();
			
			//4. 런타임에 생성될 수 있다.
			const add = new Function("x", "y", "return x+y");
			console.log(add(1,2));	//3
			
			//5. 이름이 없는 함수를 생성할 수 있다.
			const sub = function(x,y) { return x - y; }
			console.log(sub(1,2));	//-1
		</script>
	</body>
		
</html>

 

 

<!DOCTYPE HTML>

<html>
	<head>
		<meta charset="utf-8">
	</head>	
	<body>
		<h1>6 function </h1>
		<script>
			foo();	//함수도 호이스트 됩니다.	//called foo
			function foo() { console.log("called foo"); }
			foo();	//called foo
			
			//함수 표현식을 사용하여 생성된 익명 함수의 경우에는 호이스트가 발생하지 않는다.
			//bar();	//에러! Cannot access bar before initialization
			const bar = function() { console.log("called bar"); }
		</script>
	</body>
		
</html>

 

 

<!DOCTYPE HTML>

<html>
	<head>
		<meta charset="utf-8">
	</head>	
	<body>
		<h1>7 function </h1>
		<script>
			//일일이 함수 선언시 function tag 넣고 괄호 넣고 이런게 불편하다
			const pi1 = function() {
				return 3.141592;
			}			
			console.log(pi1());
			
			//화살표 함수
			const pi2 = () => {
				return 3.141592;
			}
			console.log(pi2());
			
		</script>
		
		<script>
			//화살표 함수의 표현방법 1. 매개변수가 없는 경우, 소괄호를 생략할 수 없다
			//const hello = function() { console.log("hello");}
			const hello = () => {console.log("hello");}
			hello();
			
			//화살표 함수의 표현방법 2. 매개변수가 1개인 경우, 소괄호를 생략할 수 있다.
			//const square = function(x) { return x * 2;}
			const square = x => { return x * 2;}
			console.log(square(5));
			
			//화살표 함수의 표현방법 3. 매개변수가 2개 이상인 경우, 소괄호를 생략할 수 없다
			//const mul = function(x,y) { return x * y;}
			const mul = (x,y) => { return x * y;}
			console.log(mul(5,6));
						
			
			//화살표 함수의 표현방법 4. 함수 코드가 1줄인 경우 한줄 블럭을 사용할 수 있다
			//const world = function() { console.log("world");}
			const world = () => { console.log("world"); }
			world();
			
			//화살표 함수의 표현방법 5. 함수 코드가 1줄인 경우 블럭을 생략할 수 있다
			//const goodbye = function() { console.log("goodbye~");}
			const goodbye = () => console.log("goodbye~");
			goodbye();
			
			//화살표 함수의 표현방법 6. 함수코드가 값만 반환한다면 return 키워드를 생략할 수 있다.
			//const pi = function() { return 3.141592;}
			const pi = () => 3.141592;
			console.log(pi());
			const sqr = x => x**2 ;
			console.log(sqr(10));
			
			//화살표 함수의 표현방법 7. 필요하다면 여러줄을 사용할 수 있다.
			//const area = function(r) {
			// const result = r ** 2 * 3.14;
			// return result;
			//}
			const area = (r) => {
				const result = r ** 2 * 3.14;
				return result;
			}
			console.log(area(4));
			
		</script>
	</body>
		
</html>

 

 

---

 

비동기 처리 - promise

<!DOCTYPE HTML>

<html>
	<head>
		<meta charset="utf-8">
	</head>	
	<body>
		<h1>8 promise</h1>
		<script>
			function delay(sec, callback) {
				setTimeout(function() {callback(new Date().toISOString())}, 
						   sec*1000);
			}
			
			//console.log("start");
			//delay(5, (time) => {
			//	console.log(time);
			//});
			//console.log("end");			
		</script>
		<script>
			//job1(다운로드), job2(파일저장), job3(압축해제)
			//job1,job2,job3 이 동시에 시작된다.
			delay(1, (time) => {
				console.log("job1", time);
			});
			delay(1, (time) => {
				console.log("job2", time);
			})
			delay(1, (time) => {
				console.log("job3", time);
			})
			
			//아래와 같이 처리하면 비동기적으로 처리가 되지만,
			//callbak 지옥에 빠진 케이스 (코드 복잡도)
			delay(1, (time) => {
				console.log("job1", time);
				delay(1, (time) => {
					console.log("job2", time);
					delay(1, (time) => {
						console.log("job3", time);
					})
				})
			});
		</script>
	</body>
		
</html>

 

<!DOCTYPE HTML>

<html>
	<head>
		<meta charset="utf-8">
	</head>	
	<body>
		<h1>9 promise</h1>
		<script>
			//promise 객체 생성
			//어떤 작업에 대하여 성공 또는 실패를 사용자에게 알려주기 위해 
			//2개의 콜백을 받는다. (아래 예에서는 성공하면 resolve, 실패하면 reject 호출하면 됨)
			//const job = new Promise();//Uncaught TypeError: Promise resolver undefined is not a function
			/*
			const job = new Promise( (resolve, reject) => {
				//do something..				
				//resolve("done");
				//reject("error"); //위 resolve 함수가 호출되면 reject 함수는 호출안됨
				
				//아래 코드는 다운로드를 하는 코드라고 가정
				setTimeout( ()=> {
					resolve("Download Completed");
				}, 3000);
			});
			
			//promise 객체 생성 후, 성공과 실패에 대한 처리 코드를 추가한다.
			job.then((result) => {	//성공
				console.log(result);
			});
			job.catch((reason) => { //실패
				console.log(reason);				
			});
			*/
		</script>
		<script>
			//한번 사용할 함수이므로 변수 선언을 따로 하지 않는다.			
			/*
			new Promise((resolve, reject) => {
				setTimeout( ()=> {resolve("완료");}, 3000);
			})
			.then((result)=>{console.log(result)})
			.catch((reason)=>{console.log(reason)});
			*/
			//위 코드는 어떤 작업인지를 식별하기 어렵다.
			//이를 해결하기 위해 보통 함수로 래핑(wraooing)하여 사용한다.
			const download = () => {
				return new Promise((resolve, reject) => {
					setTimeout(()=>{resolve("다운로드완료");}, 3000);
				});
			}
			download().then((result)=>{
				console.log(result);
			})
			.catch((reason)=>{
				console.log(reason);
			});
		</script>		
		<script>
			
		</script>
	</body>
		
</html>

 

 

<!DOCTYPE HTML>

<html>
	<head>
		<meta charset="utf-8">
	</head>	
	<body>
		<h1>a promise</h1>
		<script>
			/*
			delay(1, (time) => {
				console.log("job1", time);
				delay(1, (time) => {
					console.log("job2", time);
					delay(1, (time) => {
						console.log("job3", time);
					})
				})
			});
			*/
			const job1 = () => {
				return new Promise((resolve, reject) => {
				setTimeout(()=> resolve("job1"), 1000);
			})};
			const job2 = () => {
				return new Promise((resolve, reject) => {
				setTimeout(()=> resolve("job2"), 1000);
			})};
			const job3 = () => {
				return new Promise((resolve, reject) => {
				setTimeout(()=> resolve("job3"), 1000);
			})};
			
			job1().then((result)=>{
				console.log(result);
				
				//아래의 경우 동일한 콜백 지옥이다.
				//job2().then((result)=>{
				//	console.log(result);
				//})
				
				//헤결: job2에 대한 promise 객체를 반환
				//이 경우 then 함수가 호출이 끝나면 job2 함수에서 반환된 promise 객체를 반환
				return job2();
			}).then((result)=> {
				console.log(result);
			})
			.catch((reason)=> {
				console.log(reason);	//job1, job2 의 오류는 여기로 귀결된다.
			});
			
		</script>	
	</body>
		
</html>

 

 

<!DOCTYPE HTML>

<html>
	<head>
		<meta charset="utf-8">		
	</head>	
	<body>
		<h1>
			AjaxTest
		</h1>
		<script>
			//AJAX : Asynchronous Javascript And XML의 약자로 서버와 비동기 통신을 위한 기법
			//장점은 특정페이지 전체를 새로고침하지 않고도 일부만 업데이트 가능
			//https://jsonplaceholder.typicode.com/
			function fn() {
				xhr = new XMLHttpRequest();
				xhr.open("GET", "https://jsonplaceholder.typicode.com/users");
				xhr.onload = () => {
					const data = JSON.parse(xhr.response);
					console.log(data);
				};
				xhr.send();
			}
			fn();
		</script>
		<script>
			//fetch는 Promise 객체를 반환한다.
			fetch("https://jsonplaceholder.typicode.com/users")
			.then((response) => {
				//console.log(response);
				//response.text().then((result)=> {	//콜백지옥
				//	console.log(result)
				return response.json();
				})
				.then((result) => {
					console.log(result);
				});
		</script>
	</body>
		
</html>
반응형

'Node.js' 카테고리의 다른 글

Node.js - 수업 5일차  (0) 2022.08.26
Node.js - 수업 4일차  (0) 2022.08.25
Node.js - 수업 3일차  (0) 2022.08.24
Node.js - 수업 2일차  (0) 2022.08.23