시작에 앞서 본 포스팅은 velopert님의 강의를 참고하여 학습의 목적으로 정리한 내용입니다. 이점을 참고하여 주시길 바랍니다 : ) 

잘못된 정보혹은 조언등은 댓글을 통하여 언제든 환영합니다. 오늘도 저의 블로그를 들려주셔서 감사합니다 ; )

👨‍💻 자바스크립트 비동기

✅ 목차

  • 비동기 함수란?

  • Promise란?

  •  

    async~await 이란?

     

     

비동기 함수란?

비동기에 대한 설명은 다른 포스팅에서 다루었기 때문에 여기서는 생략하겠습니다.

자바스크립트는 기본적으로 단일 스레드입니다. 이러한 이유로 동시에 여러 작업들을 처리하기 위해서 비동기 작업을 위한 기능을 가지고 있는데요.

 

이러한 작업을 어떻게 구현하는지에 대하여 알아보도록 하겠습니다.

 

 

 

 

이번에는 비동기로 동작하는 setTimeout() 함수를 이용해 비동기 처리 함수를 구현해 보겠습니다.

 

 

 

이러한 상황이 발생한 이유는 비동기적으로 동작한 work함수 때문입니다. 함수의 결과값이 나오기 전에 다음 작업을 수행할 수 있도록 해주었기 때문입니다. 그래서 `console.log('다음작업')`을 먼저 수행하게 된것이죠.

그렇다면 이러한 상황에서 `console.log('다음작업')`을 비동기 작업이 끝난시점에 출력하게 하려면 어떻게 해야할까요?

바로 callBack 함수를 사용하면 됩니다.

자바스크립트는 특정함수에 파라미터로 함수를 전달이 가능합니다. 이 함수를 비동기 처리가 끝나고 실행되도록 하는것이 callBack함수 형태인데요.

 

예제를 통해서 어떤것인지 알아보도록 하겠습니다.

Promise란

CallBack 지옥을 탈출하기 위해 탄생하였습니다.

이전에도 Promise가 외부 라이브러리로서 이미 존재했었습니다. 그런데, ES6 가 표준이 되면서 공식 라이브러리로 채택되었고 별도 install 없이 사용이 가능해졌습니다.

잠깐, 여기서 callBack 지옥이 무엇인지 알아보고 넘어가도록 하겠습니다. 앞서서 특정함수에 파라미터로 함수를 전달이 가능하다 말씀을 드렸었는데, 이 함수를 비동기 처리가 끝나고 실행되도록 하는것이 callBack함수 형태라고 말씀을 드렸습니다.

만약 여기서 우리가 비동기의 처리를 다음 비동기에 사용하고 또 다시 그 결과를 다음 비동기에 처리해야할 때, 이러한 상황을 callBack지옥이라고 합니다.

 

아래 예제를 통해 짚고 넘어가도록 하겠습니다.

 

 

 

위의 예제 소스코드를 보면 알 수 있듯이 연속된 비동기처리를 구현하기 위해서 위와같이 작성하면 가독성도 매우 떨어지게 됩니다.

이러한 콜백지옥을 탈출하기 위해서 Promise를 사용하는데요

Promise를 사용하기 위해서는 일단 Promise 객체를 생성해주어야 합니다.

  • `const myPromise = new Promise((resolve, reject) => {//구현})`

  • 비동기 성공시 resolve를 호출하고

  • 실패시 reject를 호출하여 사용합니다.

예제를 통해 사용법을 알아봅시다.

비동기처리가 성공했을때의 코드

비동기처리가 실패했을때의 코드

Promise 의 장점

  • 연속된 비동기 작업이 많아져도 코드의 깊이가 깊어지지 않는다.

Promise 의 단점

  • error를 잡을때 어떤 비동기작업에서 발생했는지 찾기 힘들다.

  • 특정 조건에 따른 분기를 나누기도 어렵습니다.

  • 특정 값을 공유해가면서 작업하기도 번거롭습니다.

  • 이러한 이유로 `async~await`을 사용합니다.

async~await 이란?

ES8에서 소개된 문법입니다.

비동기 처리작업이 필요한 함수를 구현할때 특정 비동기 처리가 완료될때 까지 기다릴 수 있게 하는것이 가능합니다.

사용법은 생각보다 간단합니다.

만들고자 하는 함수 앞에 `async`를 붙여주세요. 그리고 함수 구현부({}안)에서 결과를 받아야 하는 비동기 처리함수 앞에 `await`을 붙여주면 됩니다.

아래의 예제를 통해서 이해를 더해보세요 : )

async await 을 사용한 함수는(여기서는 Process) 결과값으로 Promise 객체를 반환하게 됩니다. 그렇기 때문에 아래와 같은 소스코드를 추가로 작성이 가능합니다.

그리고 Promise에서 에러를 발생하고자 할때는 Throw 명령어를 사용합니다

`new Error();`를 통해 에러를 생성하고 `throw new Error()`를 통해 에러를 발생시킵니다.

우리가 특정 비즈니스 로직을 짜다가 에러를 발생시켜야 할때, 사용이 가능할것 같네요!

그리고 이러한 에러처리는 Promise에서 처럼 `.catch`를 사용해 처리도 가능하지만, `async~await` 구문 안에서 `try~catch` 구문을 이용해 처리도 가능합니다.

'Javascript' 카테고리의 다른 글

[ 그림판 ] web paint board  (2) 2019.07.25
Posted by Kim_gorilla

 

👨‍💻 스코프와 호이스팅

오늘은 자바스크립트 안에서 스코프라는 용어와 호이스팅이라는 용어에 대해 공부하는 시간을 가져보도록 하겠습니다. 

 

Scope(스코프) 단어 그자체를 직역하면 범위라는 의미를 가지고 있습니다. 그럼 자바스크립트에서 말하는 Scope는 어떤 범위를 의미하는 것일까요?

 

프로그래밍에서는 변수나 함수에 이름을 부여하여 의미를 갖도록 하고있습니다. 만약 이름이 없다면 변수나 함수는 그저 메모리 주소에 지나지 않게되겠죠. 그래서 프로그램은 "이름: 값"의 대응표를 만들어 사용합니다. 이 대응표의 이름을 가지고 코드를 보다 쉽게 이해하고, 또 이름을 통해 값을 저장하고, 다시 가져와 수정합니다. 

 

초기 프로그래밍 언어는 대응표를 프로그램 전체에서 하나로 관리했었는데, 여기에서 중복된 이름들 간에 이름 충돌의 문제가 발생했습니다.

 

(전통적인 방식인 var 변수형 타입을 이용하여 선언했다면, 문법적으로 오류가 발생하지 않고 두 번째 나오는 변수가 첫 번째 변수를 덮어쓰여지게 됩니다. 즉 중복된 변수들간에 충돌이 일어난 상황입니다.)

// 호이스팅 문제 발생!
var test = "this is test";
var test = "I am test too!";

 

 

(아래의 소스코드는 이러한 중복된 이름으로인한 충돌을 해결한 블록레벨 변수를 사용하여 아래와 같은 상황이 발생하면 문법적으로 오류를 발생합니다. )

// 잘못된 소스코드
let test = "this is test";
let test = "I am test too!";

그래서 충돌을 피하기 위해여 각 언어마다 "스코프"라는 규칙을 만들어 정의를 하였고 여기서 자바스크립트(ES6)는 함수레벨블록레벨렉시컬 스코프 규칙을 따르고 있습니다.

 

[스코프 레벨]

자바스크립트는 전통적으로 함수 레벨 스코프를 지원해왔고, 얼마 전까지만 해도 블록 레벨 스코프는 지원하지 않았습니다. 대표적으로 함수 레벨 스코프인 var만 사용해 왔었죠. 하지만 가장 최신 명세인 ES6(ECMAScript 6)부터 블록 레벨 스코프를 지원하기 시작했고 여기서 나온것이 let 과 const 입니다.

 

[함수 레벨 스코프 & 블록 레벨 스코프]

자바스크립트에서 var키워드로 선언된 변수나, 함수 선언식으로 만들어진 함수는 함수 레벨 스코프를 갖습니다. 즉, 함수 내부 전체에서 유효한 식별자가 된다는 이야기죠.

 

함수 내부 전체에서 유효하다는 의미는 반대개념인 블록개념과 비교하여 이해하면 쉽습니다.

 

블록레벨 스코프들은 블록안에서만 유효한데, 이를 쉽게 설명한것이 지역변수 입니다. 지역변수는 특정 블록안에서만 사용할 수 있는 변수인데요, 해당 지역(블록)을 벗어나면 소멸하여 상요할 수 없는것이 특징입니다. 하지만 함수레벨 스코프를 가지는 함수들은 특정 함수내에서 선언이 되었다면 그 장소가 if문 안이든 While문 안이던간에 그 지역(블록)을 벗어나도 해당 변수를 재 사용하는것이 가능합니다.

 

[렉시컬 스코프]

그렇다면 렉시컬 스코프란 무엇인가?

렉시컬 스코프(Lexical scope)는 보통 동적 스코프(Dynamic scope)와 많이 비교합니다.

 

동적 스코프는 프로그램의 런타임 도중의 실행 컨텍스트나 호출 컨텍스트에 의해 결정되고,

렉시컬 스코프에서는 소스코드가 작성된 그 문맥에서 결정된다. 현대 프로그래밍에서 대부분의 언어들은 렉시컬 스코프 규칙을 따르고 있습니다.

[호이스팅 이란]

호이스팅(Hoisting)을 번역하면 들어올려 나르기, 끌어 올리기로 해석됩니다. 자바스크립트에서 말하는 호이스팅도 비슷한 의미로 사용되고 있는데요 아래의 내용을통해 이게 무슨 이야긴지 살펴보도록 하겠습니다.

 

자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위의 최상단에 선언합니다. 

  • 자바스크립트 파서(Parser)가 함수 실행 전 해당 함수를 한 번 훑습니다.
  • 함수 안에 존재하는 변수/함수 선언에 대한 정보를 기억하고 있다가 생행시킵니다.
  • 유효범위: 함수 블록 "{}" 안에서 유효

즉, 함수 내에서 아래쪽에 존재하는 내용 중 필요한 값들을 위로 끌어올리는 것입니다. 이러한 모습때문에 호이스팅이라고 부르고있는 것이죠. 단, 실제로는 소스코드가 위로 끌어올려지는 것은 아니며, 자바스크립트 Parser 내부적으로 끌어올려서 처리하는 것이고 실제 메모리 상에서는 변화가 없습니다.

 

두개의 예시를 통해 호이스팅에 대해 이해를 해보도록 하겠습니다.

function foo() {
    a = 2;
    var a;
    console.log(a);
}
foo();

위의 소스코드를 실행하면 우리가 한눈에 보기에도 문법적으로 문제가 없어보이고, 실행결과 또한 예측한대로 2라는 값이 제대로 출력이 되어질겁니다.

 

그럼 소스코드상의 순서를 조금 바꿔 아래의 소스코드를 실행시켜 보겠습니다.

function foo() {
    console.log(a);
    var a = 2;
}
foo();

무언가 선언하지도 않은 변수를 먼저 사용하고 있는 모습에서 부터가 문법적으로 문제가 있어보이는데요.

하지만 var 변수는 앞서 이야기했던 함수 스코프이기 때문에 함수내에서 선언한것은 선언 위치를 기준으로 위에든 아래던간에 사용이 가능합니다.

 

그렇다면 이 소스코드도 똑같이 2라는 결과값이 나올까요? 대답은 아니오 입니다. 위의 결과로는 undefined 가 출력이 되어지는데요. 이 값은 자바스크립트에서 미리 정의된 상수값이며 의미로는 "선언이 되어있지 않음" 을 의미합니다. 분명 var a = 2 라고 초기화를 했는데 왜 선언이 되어있지 않다고 하는지에 대하여 알아보도록 하겠습니다.

 

자바스크립트 엔진은 코드를 인터프리팅 하기 전에 그 코드를 먼저 컴파일합니다. var a = 2를 하나의 구문으로 생각하지 않고 다음의 두개 구문으로 분리하여 봅니다.

  1. var a; (선언)
  2. a = 2; (할당=초기화)

변수 선언 단계와 초기화 단계를 나누고, 선언 단계에서는 그 선언이 소스코드의 어디에 위치하든 해당 스코프의 컴파일 단계에서 처리해 버리는 것입니다. 때문에 이런 선언단계가 스코프의 꼭대기로 호이스팅("끌어올림")되는 작업이라고 볼 수 있는 것이죠.

 

 

[호이스팅 대상]

이러한 호이스팅이 발생되는 대상에는 무엇이 있을까요?

 

호이스팅은 var변수 선언과 함수선언문에서만 일어납니다.

  • var면수/함수의 선언만 위로 끌어 올려지며, 할당은 끌어 올려지지 않는다.
  • let/const 변수 선언과 함수 표현식에서는 호이스팅이 발생하지 않는다.
    (var 보단 let 과 const를 사용하자)
    • 함수 표현식이란 익명함수등을 이용한 함수사용을 의미합니다.

[호이스팅의 문제]

호이스팅이 자주 발생하게 된다면 개발자가 코드를 해석하는 가독성이 떨어지게 되고 이는 유지보수의 어려움으로 이어지게 됩니다.

 

참고사이트

'Javascript > 이론' 카테고리의 다른 글

JavaScript | 클로저란 무엇인가?  (0) 2020.06.06
Posted by Kim_gorilla

👨‍💻 JavaScript | 클로저란 무엇인가?

 

오늘은 자바스크립트에서 클로저라는 개념에 대해서 이해하고 왜 사용하는지에 대하여 알아보겠습니다.

우리가 학습할 내용을 정리해보자면 아래와 같습니다.

 

  1. 클로저의 개념
  2. 클로저는 언제 사용되어지는가?
  3. 클로저를 왜 사용하는가?

1. 클로저의 개념

"생활코딩"에서 클로저에 대한 정의를 다음과 같이 설명하고 있습니다.

클로저(closure)는 내부함수가 외부함수의 맥락(context)에 접근할 수 있는 것을 가르킨다. 클로저는 자바스크립트를 이용한 고난이도의 테크닉을 구사하는데 필수적인 개념으로 활용된다.  

참고사이트

자바스크립트에서는 특정 함수 내부에 또다른 함수를 선언하는것이 가능한데요, 이것을 '내부함수' 라고 부르며 이것을 통해 구현한 것이 '클로저' 입니다.

 

일단 내부함수가 무엇인지 알아보도록 하겠습니다. 아래의 예제를 보시면 innerFunc이라는 함수 안에서 익명함수를 return문을 통해 반환하는 것을 보실 수 있습니다. 

이와같이 함수 내부에 또다른 함수를 선언한것을 의미하며 위에 코드의 실행결과로는 아래와 같습니다.

여기서 흥미로운 사실은 내부함수는 외부함수의 지역변수(위코드에서는 text변수)에 접근이 가능하다는 점입니다.

 

일반적으로 우리가 알고있는 함수의 지역변수는 함수의 라이프사이클과 함께하며, 본인의 역할을 다 하고 종료되었을때 가지고 있던 지역변수도 같이 사라지게 됩니다.

 

하지만, 내부함수를 통해 접근한 외부함수의 지역변수들의 값은 외부함수의 실행이 끝나서 소멸된 이후에도 외부에서 저장한 내부함수를 통해 접근이 가능합니다. 말로 설명하니 조금 어려운것 같으니 예제를 통해 알아보도록 하겠습니다.

 

아래의 예제에서는 외부함수의 매개변수로 특정 이름(name)을 받아와 새로운 문자열(text)을 만들었습니다.  그리고 이 문자열을 내부함수를 통해 console에 출력을 하게 하였습니다. 

위의 14~16줄을 보면 외부함수를 실행시키는 부분을 보실 수 있습니다. 그리고 이 외부함수는 16줄 이후에서 종료되어 사라지게 되어지죠. 실행된 각 외부함수들은 내부함수들을 반환하여 test1~3 변수에 각각 저장되어지게 됩니다.

 

여기서 각 test1~3변수에 저장이 된 주체는 내부함수기 때문에 종료되어 소멸된 외부함수의 지역변수들 또한 소멸이 되어야 할것 같지만, 20~22번줄을 실행한 결과가 아래와같이 나오는 것을 보실 수 있습니다.

 

클로저는 내부함수와 밀접한 관계를 가지고 있는 주제입니다. 내부함수는 외부함수의 지역변수에 접근 할 수 있는데 위의 결과처럼 외부함수의 실행이 끝나서 외부함수가 소멸된 이후에도 내부함수가 외부함수의 변수에 접근 할 수 있습니다. 이러한 메커니즘을 클로저라고 합니다.

 

요약해서 클로저란 내부함수가 외부함수의 지역변수에 접근 할 수 있고, 외부함수는 외부함수의 지역변수를 사용하는 내부함수가 소멸될 때까지 소멸되지 않는 특성을 의미합니다.

참고사이트

2. 클로저는 언제 사용되어지는가?

클로저는 내부함수와 밀접한 관계가 있다고 위에서 설명을 드렸는데요, 여기서 내부함수는 외부함수의 지역변수를 가져다 사용이 가능하다 말씀드렸었습니다. 사실 내부함수는 외부함수의 지역변수 뿐 아니라 매개변수값도 참조해서 사용이 가능한데요, 이러한 기능은 창의적인 방법으로 활용될 수 있습니다.

 

아래의 내부(private)변수예제는 더글라스 크락포드(Douglas Crockford)에 의해 처음 시연되었습니다.

클로저와 객체(Dictionary)를 이용해서 마치 클래스의 Getter 함수, Setter함수와 같은 기능을 하도록 구현이 가능합니다. 이렇게 작성하게 된다면 그저 외부함수 지역변수의 값을 읽어오는것 뿐 아니라 그 값을 변경하는것이 가능해집니다. 

 

또 다른 예제로는 반복문 클로저 예제가 있습니다. 이 예제는 단순히 0~9의 값을 setTimeout 함수를 이용해 출력하는 함수를 구현하는 것입니다. 만약 클로저를 고려하지 않고 이를 구현하라고 한다면 아래와 같이 작성을 하게 될것입니다.

하지만 이렇게 작성된 코드의 결과는 우리가 예상했던 0~9의 값을 출력하는 것이 아니라 10의 값을 반복해서 찍어주게 됩니다.

이유즉슨, setTimeout 함수에 인자로 넘어간 익명함수는 모두 0.1초 뒤에 호출이 되어지게 될텐데 그 시간 사이에 반복문이 전부 돌아 i값을 10으로 만들어 버렸기 때문입니다.

 

이를 우리가 원했던 0~9의 값이 출력되도록 하기 위해서는 클로저를 이용하여 매 반복시 증가되는 i값을 매개값으로 받는 외부함수 하나를 생성하고 그안에서 i값을 받아 setTimeout을 실행하는 내부함수를 만들어 주면 됩니다.

이렇게 해주게 되면, 외부함수를 반복횟수만큼 실행한 상황이 만들어지고 각 외부함수 매개값으로 i값을 넘겨주었기 때문에 이를 내장함수가 참조해서 사용할 수 있게 되어지는 것이죠.

 

이를 실행하게 되면 우리가 예측한대로 잘 출력이 되어집니다.

참고사이트

3. 클로저를 왜 사용하는가?

자바스크립트에서는 함수가 선언될 때 자신이 접근할 수 있는 범위를 정하고 기억하고 있는데 이것을 렉시컬 스코프라고 합니다. 그리고 이런 렉시컬 스코프에 의해 외부 함수의 환경을 기억하고 있는 내부 함수가 클로저입니다.

 

여기서 "lexical"이란, 어휘적 범위 지정(lexical scoping) 과정에서 변수가 어디에서 사용 가능한지 알기 위해 그 변수가 소스코드 내 어디에서 선언되었는지 고려한다는 것을 의미합니다. 단어 "lexical"은 앞에서 정의한 의미를 가지며, 중첩된 함수는 외부 범위(scope)에서 선언한 변수에도 접근할 수 있습니다.

 

클로저는 클래스와 꽤나 비슷한 구조를 가지고 있습니다. 그렇기 때문에 클래스 개념이 없는(ES6에서는 있습니다.) 자바스크립트에서는 클래스를 대신하여 쓰이기도 합니다. 

 

그렇다면 객체지향적 개발을 위해서 클로저를 무조건 사용하는것이 좋을까요?

그에대한 대답은 "적절한 상황에 사용하되 메모리할당을 해제시켜주자" 라고 답변드리고 싶습니다.

 

클로저는 각자의 환경을 가집니다. 이환경을 기억하기 위해서 외부함수자체를 소멸시키지 않고 기억하기 때문에 당연히 메모리 또한 소모되어질겁니다. 그렇기 때문에 클로저를 생성해놓고 참조를 제거하지 않는 것은 C++에서 동적할당으로 객체를 생성해놓고 메모리할당을 해제하지 않는것과 비슷합니다. 

즉, 클로저를 통해 내부 변수를 참조후 사용이 끝나면 참조를 제거하는것이 메모리 효율에 좋다고 볼 수 있습니다.

그렇기에 위와같이 답변을 드릴수 있겠네요 : )

 

참고사이트

 

 

📌 서브제목

.

 

'Javascript > 이론' 카테고리의 다른 글

JavaScript | 스코프와 호이스팅  (0) 2020.06.07
Posted by Kim_gorilla

1️⃣ What is AJAX?

**Ajax(Asynchronous JavaScript and XML)**는 비동기적인 웹 제작을 위한 기법입니다.

 

 

2️⃣ ​Why we use this?

웹사이트 내의 특정 페이지의 데이터 변화가 존재할 때 페이지를 **새로고침(refresh)**해야 적용이 됩니다. 이는 데이터의 변화빈도가 많다면 그만큼 **새로고침(refresh)**도 많이 수행해 주어야 한다는것을 의미합니다.

 

이러한 방법은 매우 불편하고 비효율적인 방법이며, 우리가 새로고침(refresh)이전에 가지고 있던 데이터에 비해 새로고침(refresh)이후에 새로 받은 데이터가 크게 변화된게 없다면 아주 작은 변화를 위해 이전에 받았던 데이터까지 몽땅 다 받아와야 함을 의미합니다.

 

이것은 매우 불편한 진실이고 트래픽이 증가하게되어 비효율적인 로딩이 많아지게 됩니다.
이러한 상황에서 우리는 AJAX통신을 사용합니다. AJAX이름에서 맨 앞의 **A는 synchronous**라는 의미로서 비동기라는 의미를 가지고 있습니다.

 

여기서 동기와 비동기에 대한 빠른 이해를 위해 예시를 들어 설명해 드리겠습니다.

 

 

가정 )

 

자 상황을 설정해 보죠, 우리는 야채를 사기위해서 야채가게에 서있다고 가정해 봅시다. !

 

 

이러한 상황에서 우리는 원하는 야채를 사기위해서 자신의 차례가 올때까지 줄을 기다려야 하며, 그동안은 아무 작업도 하지 못하게 됩니다.

 

이것이 일반적인 우리가 웹서버를 만들었을때 브라우저와 서버가 데이터를 주고 받는 모습입니다. 우리가 이전에 하던 작업을 끝내기 전까지는 다른 작업을 할 수 없음을 의미하고 그리고 이것을 **동기방식** 이라고 부릅니다.

 

이번에는 **비동기 방식**상황을 살펴보겠습니다. 이전예시와는 다르게 야채를 사기위해 줄을서서 기다리지 않고 번호표를 뽑은 후에 다른 작업을 하러 갑니다.

번호표를 뽑았기 때문에 내차례가 돌아왔을때 잠깐 들러서 원래 하려던 볼일을 보고 다른일을 하러 가면됩니다.

 

이처럼 이전 동작이 안 끝났어도 일단 제어권을 반납한 후 자신의 할일 계속하는 방식을 비동기 방식이라고 부르며, 이러한 방식을 통해서 필요한 데이터만을 쏘옥! 받아온 후에

document.getElementById("tag").innerHTML = 'hi';

 

를 이용해 받아온 데이터를 화면에 재구성하는 방법이 있습니다.

 

3️⃣ How to use AJAX?

🖐 JSON이란?

Javascript Object Notation 의 약자입니다.

  • JSON은 경량(Lightweight)의 DATA-교환 형식

  • Javascript에서 객체를 만들 때 사용하는 표현식을 의미한다.

  • JSON 표현식은 사람과 기계 모두 이해하기 쉬우며 용량이 작아서, 최근에는 JSON이 XML을 대체해서 데이터 전송 등에 많이 사용한다.

  • 특정 언어에 종속되지 않으며, 대부분의 프로그래밍 언어에서 JSON 포맷의 데이터를 핸들링 할 수 있는 라이브러리를 제공한다.

🖐 JSON 형태는?

'{ "firstName": "Kwon", "lastName": "YoungJae", "email": "kyoje11@gmail.com" }'

보시는것처럼 javascript의 list 형태 (python에서는 dictionary 형태죠?)를 띕니다.

🖐 주로 사용되는 JSON함수!

  • **JSON.stringify()**

    • JSON.stringify() 메소드는 인수로 전달받은 자바스크립트 객체를 문자열로 변환하여 반환합니다. (EX. js에서 Server로 데이터를 넘겨서 Server에서 데이터를 사용해야 하는 상황)

    • JSON.stringify(value)
    • value에는 변환할 자바스크립트 객체를 전달합니다.

      이 메소드는 UTF-16으로 인코딩된 JSON 형식의 문자열을 반환합니다.

  • **JSON.parse()**

    • JSON.parse() 메소드는 JSON.stringify() 메소드와는 반대로 인수로 전달받은 문자열을 자바스크립트 객체로 변환하여 반환합니다. (EX. Server에서 js로 보낸 데이터를 객체로 만들어서 사용하는 상황)

    • JSON.parse(text)
    • // JSON 형식의 문자열 var data = '{"name": "식빵", "family": "웰시코기", "age": 1, "weight": 2.14}'; var dog = JSON.parse(data); // JSON 형식의 문자열을 자바스크립트 객체로 변환함. document.getElementById("json").innerHTML = dog + "<br>"; document.getElementById("json").innerHTML += dog.name + ", " + dog.family;
  • **toJSON()**

    • 자바스크립트의 toJSON() 메소드는 자바스크립트의 Date 객체의 데이터를 JSON 형식의 문자열로 변환하여 반환합니다.

      따라서 이 메소드는 Date.prototype 객체에서만 사용할 수 있습니다.

    • var date = new Date(); // 자바스크립트 Date 객체 var str = date.toJSON(); // Date 객체를 JSON 형식의 문자열로 변환함. document.getElementById("json").innerHTML = date + "<br>"; document.getElementById("json").innerHTML += str;

⭐️ 실습!!

빠른 실습을 위해서 우리는 Jquery라이브러리를 사용한 AJAX 통신을 해볼것입니다.

(※ jquery 기본문법 공부 참고는 아래 사이트 참고바랍니다! ※) <https://www.w3schools.com/jquery/default.asp>

 

 

👨‍💼: ​jquery CDN추가해줍니다.

 

 

 

 

 

👨‍💼 : $.ajax의 문법은 아래와 같습니다.

jQuery.ajax( [settings ] )

setting는 Ajax 통신을 위한 옵션을 담고 있는 객체가 들어갑니다. 주요한 옵션을 열거해보면 아래와 같습니다.

  • **data** 서버로 데이터를 전송할 때 이 옵션을 사용한다.

  • **dataType** 서버측에서 전송한 데이터를 어떤 형식의 데이터로 해석할 것인가를 지정한다. 값으로 올 수 있는 것은 xml, json, script, html이다. 형식을 지정하지 않으면 jQuery가 알아서 판단한다.

  • **success** 성공했을 때 호출할 콜백을 지정한다. Function( PlainObject data, String textStatus, jqXHR jqXHR )

  • **type** 데이터를 전송하는 방법을 지정한다. get, post를 사용할 수 있다.

  •  

    **error** 실패했을 때 호출할 콜백을 지정한다.

     

     

👨‍💼 : python에서 json을 사용하기 위한 라이브러리를 받습니다.

pip install simplejson

 

👨‍💼 : ​그 후 views.py 상단에 다음과 같이 라이브러리를 임포트 해줍니다.

import simplejson as json

 

👨‍💼: ​DATA를 views.py에서 반환할때

return HttpResponse(json.dumps(context), content_type="application/json")

 

 

 

 index.html 결과 화면

 

Hello, world!

hello

 

 

▶ index.html

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

    <title>Hello, world!</title>
  </head>
  <body>
    <h1>Hello, world!</h1>

    <p id="example">hello<br></p>
    <input type="button" id="execute" value="execute" />    

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script>
        $('#execute').click(function(){
            $.ajax({
                url:"{% url 'ajax' %}",
                dataType:'json',
                success:function(data){
                    var str = '';
                    alert('ajax통신성공!!');
                    alert(data);
                    for(var name in data){
                        str += '<li>'+'1.KEY: '+name+'</li>';
                        str += '<li>'+'2.VALUE: '+data[name]+'</li>';
                    }
                    alert(str)
                    $('#example').html('<ul>'+str+'</ul>');
                },
                error: function(request, status, error){ // 통신 실패시 - 로그인 페이지 리다이렉트
                    alert("ajax통신실패...")
                    alert(error)
                    alert(request)
                    window.location.replace("{% url 'main' %}")
                    //  alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
                },
            })
        })
    </script>
    </body>
</html>​

 

 

 

 example앱 ➡️ urls.py

from django.contrib import admin 
from django.urls import path, include 

urlpatterns = [ 
	path('admin/', admin.site.urls), 
	# example app의 urls.py로 이동합니다. 
	path('', include('example.urls')), 
    ]

 

 example앱 ➡️ views.py

from django.shortcuts import render 
from django.http import HttpResponse  # 이것 추가해줍니다. 
import simplejson as json # 이것 추가해줍니다. 

# Create your views here. 
def main(request): 
	return render(request, 'index.html') 

def ajax(request): 
	example = 'hello AJAX!' 
    context = { 'hello' : example } 
    return HttpResponse(json.dumps(context), content_type="application/json")

 

 

 

 

 

 

 

Posted by Kim_gorilla