반응형

📢<form> 태그

▼ 사용자 입력을 위한 폼을 만드는데 사용

▼ Action = 양식이 제출 될 때 폼 데이터를 전송하는 위치지정

▼ Method = post , get

- 폼 데이터를 전송할때 사용하는 방법을 지정

- get : url 에 데이터가 출력되면서 전송되는 형태

- post : http request 본 문 내에서 전달되는 방식

form 태그에 action 하고 method 속성을 안넣으면 웹표준검사에서 통과를 못한다

 

📋<fieldset>

- 폼의 그룹

- 요소 주위에 상자를 그림

 

📋<legend>

- <fieldset> 의 제목을 정의

<form action="" method="">
    <fieldset>
        <legend>로그인</legend>
        로그인이 실제 들어갈 코드
    </fieldset>
</form>

 

반응형

'프로그래밍 > HTML' 카테고리의 다른 글

HTML4 - LIST 태그 (UL , OL , DL 태그)  (0) 2019.04.18
HTML4 - Table (테이블)  (0) 2019.04.16
HTML4 - form 태그의 enctype 속성 (파일 업로드)  (3) 2019.04.16
HTML4 - Entity Code  (0) 2019.04.15
HTML4 - <IMG> 태그 , <a> 태그  (0) 2019.04.02
반응형

프로젝트를 진행하다보면 HTTP 통신을 통해 데이터를 가져와야할 경우가 있습니다. 기본적으로 HTTP통신은 비동기적으로 이루어집니다. 그렇다보니 데이터를 받아오기전에 Rendering이 이루어지는 경우도 있고 미리 연산처리를 해버려 에러를 발생시키는 경우도 빈번하게 발생합니다.

이번 포스팅에서는 위와 같은 일을 방지하기 위해 Javascript 에서의 비동기를 동기로 실행하는 방법에 대해서 알아보려합니다 👍

📋비동기 / 동기

우리는 카페에가서 음료를 주문하고 진동벨을 받아옵니다. 자리에가서 앉아 있다 진동벨이 울리면 커피를 받아옵니다. 이를 ‘비동기 처리’에 비유할 수 있습니다.

각자의 일을 처리하다 자신의 차례가 오면 자신의 일을 수행합니다. 서로에게 영향을 주지 않습니다.

진동벨이 없다고 생각해보세요 카페에가서 음료를 시키고 음료가 나올때까지 카운터에서 기다려야한다면 우리는 커피가 나오기전까지는 자리에 앉아 업무를 볼 수 없을거에요 이처럼 앞의 일이 끝나야 다음일을 처리할 수 있는 것을 ‘동기의 처리’에 비유할 수 있습니다.

📋비동기를 동기로 동작시키는법

자바스크립트에서의 비동기를 동기로 동작시키는 대표적인 3가지의 방법을 알아보겠습니다.

Callback Function

Promise

Async / Await

Generator (이 포스트에서는 다루지 않습니다)

📋 1. Callback

첫번째로 Callback을 이용한 방법을 알아보겠습니다.

기본적인 Callback의 사용법은 위와 같습니다 😉

a 는 callback 즉 function을 받는 함수입니다.

a 는 받은 함수에 ‘i am A’ 라는 값을 넣어줍니다.

b 는 a에서 넘겨준 ‘i am A’ 라는 값을 받아 console 에 찍어줍니다.

위의 코드의 동작을 이해하셨다면 비동기를 동기로 바꾸는 코드도 쉽게 이해하실 수 있습니다.

두개의 함수가 있습니다.

step1은 실행 후 2초가 걸리고, step2는 1초가 걸립니다.

우리는 step1이 실행되고 step2 가 실행되기를 바랍니다.

위의 코드를 실행해보면 우리가 원했던 결과가 나오지 않습니다.

step2 가 실행하고 step1 이 실행됩니다.

어떻게 하면 우리가 원하는대로 실행시킬 수 있을까요 ? 바로 ‘Callback’ 을 이용하면 됩니다.

step1 은 함수를 인자로 받는 함수입니다.

step1 은 받은 함수를 실행해주는 역할을 합니다.

우리가 의도한대로 step1 이 실행된 후 step2 가 실행됩니다.

위와 같은식으로 Callback을이용하면 비동기를 동기처럼 동작하게 할 수 있습니다.

하지만 지금은 함수가 2개 뿐이지만 함수가 많아질 수록 함수의 깊이가 깊어집니다. 표현방법 2 처럼 말이죠 함수안에 함수 함수안에 함수…. 그안에 또 함수 … 다들 한번쯤 들어보셨을만한 Callback Hell 이 되는 것이죠 .. 그래서 조금더 깔끔하게 처리할 방법이 필요했습니다.

그것이 2번째 방법인 Promise 입니다.

📋2. Promise

기본적인 Promise 객체의 사용법 입니다.

foo 는 Promise 객체를 Return 합니다. 그렇기 때문에 foo().then 처럼 이어갈 수 있습니다.

foo().then 에서 then은 foo의 동작이 마무리된 후 동작합니다. Promise resolve 안에 넣어준 값이 들어옵니다.

then 을 계속 이어쓸 수 있습니다

Callback 으로 해결했던 것을 Promise 로 변경해보겠습니다.

a는 Promise 객체를 반환합니다. 그렇기 때문에 a().then 을 통해 순서를 제어할 수 있습니다. then 은 a의 동작이 마무리된 후 실행됩니다.

a 가 실행되며 console.log(‘a run …..’) 이 제일 먼저 실행되고

resolve를 통해 then 으로 (str === ‘a run …..’) 을 넘겨줍니다.

a의 실행이 끝나고 then 에서 b를 실행하며 str을 넘겨줍니다. 이때 console.log(‘b run …..’) 이 찍히게 됩니다.

마지막으로 1초 후 console.log(‘넘겨받은 값: ’, str) 이 찍히게 됩니다.

또 여러개의 비동기 작업이 있을때 비동기 작업이 모두 완료된 후에 어떤 작업이 이루어져야 할때도 Promise를 이용할 수 있습니다.

2개의 작업이 있습니다. 한가지 작업은 1초가 걸리고 다른 한가지 작업은 2초가 걸립니다. 우리가 원하는 것은 두개의 작업이 ‘모두’ 마무리 된 후에 다른 작업이 이루어지기를 바랍니다.

Promise.all 에 [첫번째 Promise, 두번째 Promise] 의 형태로 넘겨주면 모든 Promise의 작업이 끝난후 then 에 결과값을 배열형태로 넘겨줍니다

어떤가요 Callback 보다는 편리해졌나요 ? 하지만 Promise 또한 깊이가 깊어진다면 가독성이 현저히 떨어질 수 있습니다. 사실 Promise를 사용하는데 보기가 너무 힘들고 불편한 현상이 생겼다면 (본인의 코드를 의심해봐야 될 수 있습니다…😉)

📋3. Async / Await

마지막으로 살펴볼 방법은 Async / Await 입니다.

Async /Await 은 말그대로 동작을 일시정지 시킨것처럼 보이게 해줍니다. Promise 나 Callback 보다는 직관적인 코드 패턴을 가질 수 있습니다. (Async 와 Promise 의 차이점에 대해서는 후에 포스트에서 다뤄볼 예정입니다)

async 함수 표현식을 이용합니다.

async 함수 내부에서는 promise 객체들의 순서를 await을 이용하여 순서 조절이 가능합니다.

foo 는 async 함수입니다.

foo 를 실행가된다면 console.log(‘foo run….’) 이 가장 먼저 찍히게되고 아래 await 을 만나게 됩니다.

promise() 은 Promise 객체입니다. promise() 을 실행하면서 console.log(‘promise run ….’) 이 찍히게 되고 2초 후에 resolve(10) 을 실행하게됩니다. 앞에서 살펴봤던 Promise 에서는 then으로 10 으로 들어가지만 await 을 이용하게되면 10 이 return 됩니다. 즉 const num = 10 이 됩니다.

promise() 종료 후 num 에 10이 들어오고 console.log(‘num’, 10) 이 실행된 후 종료됩니다.

📢마무리

비동기를 동기처럼 사용할 수 있는 3가지 방법에 대해서 알아봤습니다. 어떤 것이 좋고 어떤 것이 안 좋다고 말하기에는 저의 경험과 지식이 아직 부족하기도 하고 상황마다 필요한 것들이 다르기 때문에 감히 말할 수는 없습니다.

Promise와 Async 는 디버깅 시 에러가 걸리는 포인트가 다르기도 하고 개인의 취향에 따라 어떤 것이 더 보기 편하다 나쁘다 등등 굉장히 많은 이야기가 오가는 것으로 알고 있습니다. 이에 대한 이야기는 자료를 더 수집한 후 뒤에 포스터에서 정리해보려 합니다. 😉

-출처 https://medium.com/@appear.ko/javascript-async-to-sync-157c57208598

 

반응형
반응형

📢JAVASCRIPT THROW 예외처리

▼ 내용
throw 에 에러가 걸리면 이하 구문은 실행안하고 catch문으로 들어간다

💻코드

function getRectArea(width, height) {
  if (isNaN(width) || isNaN(height)) {
    console.log("시작 1");
    throw "Parameter is not a number!";
    console.log("시작 2");
  }
  console.log("시작 3");
}

console.log("시작 4");

try {
  getRectArea(3, 'a');
  console.log("시작 5");
}
catch(e) {
  console.log("에러22"+e);
  // expected output: "Parameter is not a number!"
}

//console.log 에러일경우
> "시작 4"
> "시작 1"
> "에러22Parameter is not a number!"

//console.log 정상일경우
> "시작 4"
> "시작 3"
> "시작 5"
반응형
반응형

💻코드

<div id="canvas-realtile-graph"><svg width="355" height="110"></svg></div>
<script> 	
			var n = 60;
			var dataGal=[];
		    //random = d3.randomNormal(0, .2),
		    //dataGal = [0.3639, 0.4862, 0.7588, 0.5905, 0.3522, 0.8548, 0.1268, 0.9583, 0.1176, 0.1361, 0.8377, 0.4384, 0.5754, 0.7842, 0.9094, 0.7698, 0.1691, 0.0518, 0.8581];
		    //dataGal = [5,10,15,20,25,30,35,40];
/* 			dataGal = [ 
							  { "x": 1558583546*1000,   "y": 0.3639},  
							  { "x": 1558583547*1000,  "y": 0.4862},
							  { "x": 1558583548*1000,  "y": 0.7588}, 
							  { "x": 1558583549*1000,  "y": 0.5905},
							  { "x": 1558583550*1000,  "y": 0.8548},  
							  { "x": 1558583551*1000, "y": 0.9583}
							]; */
			
			var svg = d3.select("svg"),
			    margin = {top: 20, right: 20, bottom: 20, left: 40},
			    width = +svg.attr("width") - margin.left - margin.right,
			    height = +svg.attr("height") - margin.top - margin.bottom,
			    g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
			
			
			var abcd3 = (1558583546+60)*1000;
			var abcd2 = 1558583546*1000;
			
			var x = d3.scaleTime()
			    .domain([abcd2, abcd3])
			    .range([0, width]);
			
			var y = d3.scaleLinear()
			    .domain([0, 1])
			    .range([height, 0]);
			
			var line = d3.line()
			    .x(function(d) { return x(d.x); })
			    .y(function(d) { return y(d.y); });
			
			g.append("defs").append("clipPath")
			    .attr("id", "clip")
			  .append("rect")
			    .attr("width", width)
			    .attr("height", height);
			
			g.append("g")
			    .attr("class", "axis axis--x")
			    .attr("transform", "translate(0," + y(0) + ")")
			    .call(d3.axisBottom(x).ticks(3).tickFormat(d3.timeFormat("%M:%S")));
			
			g.append("g")
			    .attr("class", "axis axis--y")
			    .call(d3.axisLeft(y).ticks(5));
			
			g.append("g")
			    .attr("clip-path", "url(#clip)")
			  .append("path")
			    .datum(dataGal)
			    .attr("class", "line")
			  .transition()
			    .duration(1000)
			    .ease(d3.easeLinear)
			    .on("start", tick);
			
 			function tick() {
 				console.log("tick 조회")
			  /*var gal = { "x": 1558583552*1000, "y": 0.2590};*/
			  var gal = { "x": new Date().getTime(), "y": Math.floor(Math.random()*10000)/10000};
 				
			  dataGal.push(gal);
			  rescale();
			  
			  // Redraw the line.
			  d3.select(this)
			      .attr("d", line)
			      .attr("transform", null);

			  d3.active(this)
			      //.attr("transform", "translate(" + x(-1) + ",0)")
			    .transition()
			    .on("start", tick);

			  if(dataGal.length>=60){
				  dataGal.shift();
			  } 
			} 
			
			
			function rescale() {
			    
			    y.domain([0,1.0]);  // 스케일 바꾸기
			    x.domain([new Date().getTime()-60000,new Date().getTime()]);
			    
			    g.select(".axis--y").remove(); //스케일 라벨 지우기
			    g.select(".axis--x").remove(); 
				
			    g.append("g")
			    .attr("class", "axis axis--y")
			    .call(d3.axisLeft(y).ticks(6)); //스케일 라벨 그리기
			    
				g.append("g")
			    .attr("class", "axis axis--x")
			    .attr("transform", "translate(0," + y(0) + ")")
			    .call(d3.axisBottom(x).ticks(3).tickFormat(d3.timeFormat("%M:%S")));
			
			}
			
			
			
			function ParseToDate(d){
				return d.getHours()+":"+d.getMinutes()+":"+d.getSeconds();
			}

</script>
반응형
반응형

📢 [JAVA] 리터럴과 형변환

📋 상수와 리터럴

▼ 상수 (constant) : 변하지 않는 수 (ex : final 등으로 사용)

▼ 리터럴 (literal) : 프로그램에서 사용하는 모든 숫자,값,논리 값 (ex : 숫자,10,3.14,true,'a')

모든 리터럴은 상수 풀 (constant pool)에 저장되어 있음

상수풀에 저장될 때 정수는 int (4byte) , 실수는 double (8byte) 로 저장됨.

12,345,678,900L 이렇게 큰 숫자의 경우 L 을 붙여 8바이트로 처리됨

위의 각 숫자들이 상수풀에 저장되어있다가 프로그래밍을 할때 바로 꺼내와서 사용

 

📋 형변환

▼ 서로 다른 자료형의 값이 대입되는 경우 형 변환이 일어남

묵시적 형 변환 (implicit type conversion):

 작은수에서 큰 수로 덜 정밀한 수에서 더 정밀한 수로 대입되는 경우

명시적 형 변환 (explicit type conversion) :

 변환 되는 자료 형을 명시 자료의 손실이 발생 할 수 있음

묵시적 형 변환의 경우 별다른 코딩은 안해도 되고 명시적 형변환의 경우 캐스팅을 해줘야함

💻코드1

byte bNum = 10;
int iNum = bNum; 
// byte 는 1바이트 int 는 4바이트 따라서 묵시적 형변환

System.out.println(bNum); //10
System.out.println(iNum); //10

int iNum2 = 2;
float fNum = iNum2; 
// 정수형보다 실수형이 더 크기떄문에 별도의 캐스팅없이 묵시적 형변환

System.out.println(fNum); //20.0

double dNum;
dNum = fNum + iNum;
//fNum은 float 형이기 때문에 iNum 은 float 형식으로 형변환 1번
//dNum (double형)으로 값을 넣어주기 떄문에 fNum , iNum  (double)형으로 형변환 2번
System.out.println(dNum); //30.0




int iNum = 1000; 
byte bNum = (byte) il
System.out.println(bNum); //-24
// byte는 2의-7승(-127) ~ 2의 7승(127) 까지 표현하기 때문에
// iNum의 데이터가 손실이 된다. 명시적 형변환

double dNum = 1.2;
float fNum = 0.9F; 

int iNum1 = (int)dNum1 + (int)fNum;
int iNum2 = (int)(dNum1 + fNum);
System.out.println(iNum1); //1
System.out.println(iNum2); //2
// 실수를 int로 형변환 하면 소수점이하 자리는 버림이 된다.
// 따라서 iNum1 은 1+0 이고 iNum2 는 2.1 에서 소수점을 버리게 된다.

📋 진법 변환

▼2진수 , 8진수 , 16진수 를 각 진법으로 쓰면

2진수 0b~~~ (ex: 0b1010)

8진수 0~~~~ (ex: 012)

16진수 0x~~~~ (ex: 0xA)

(대문자 소문자는 가리지 않습니다.)

💻코드2

int num = 10; 
int bnum = 0b1010;
int onum = 012;
int xnum = 0xA;

System.out.println(num ); //10
System.out.println(bnum ); //10
System.out.println(onum ); //10
System.out.println(xnum ); //10

위처럼 진법변환을 프로그래밍 코딩을 할수 있다.
 
반응형

'프로그래밍 > Java' 카테고리의 다른 글

JAVA - 인스턴스, 힙 메모리  (1) 2022.01.01
Java - 라운드 로빈 (Round Robin) 예제  (0) 2019.05.29

+ Recent posts