javascript의 동기 / 비동기
[참고] javascript 비동기 동작과정
- javascript의 promise가 탄생하게 된 이유
요약 : 비동기를 위한 callback이 많아지자 그것을 관리하기 위하여
자바스크립트는 Single Thread 방식이며, 모든 비동기 이벤트(Event Callback, 타이머(setTimeout, setInterval)는 같은 Thread 위에서 실행된다.
그러므로 기본적으로는 동기 방식으로 진행된다.
동기 방식
동기 방식이란, 작업이 들어온 순서에 맞게 차근차근 하나씩 진행되는 것이다. 순서에 맞게 빨리빨리 진행되는 장점이 있지만, 여러 가지의 일을 동시에 처리할 수 없는 단점이 있다.
비동기 방식
동기방식의 단점을 보완하기 위해 탄생되었다고 보여지는 비동기방식. 비동기 방식은 여러가지 일을 한꺼번에 처리할 수 있지만, 동기 방식보다 처리 속도가 조금 떨어질 수도 있다.
동기 방식은 실행 함수가 끝난 뒤 되돌아오는 반환 함수, 즉 콜백 함수를 활용하여 일 처리 순서를 제어하는 것이다. 예를 들어 페이스 북에 댓글을 달 때, 페이지 새로고침을 하지 않는다든가, 대용량 페이지를 로드할 때 프로세스 진행 상황을 프로그래스바 혹은 모래시계 아이콘으로 보여준다든가 하는 방식으로 말이다.
자바스크립트의 콜백함수란?
이벤트 함수가 실행된 후 결과가 되돌아오는 시점에서 실행되는 함수다.
이러한 장점이 있다 보니 필요에 따라 사용되는 콜백 함수들이 하나씩 늘게 되었다. 그런데 이 콜백 함수가 난무하게 되면 개발자가 코드를 알아보기 힘들뿐더러 디버깅, 유지보수 하기 매우 힘들어진다. 그러한 점을 극복하기 위해 콜백 덩어리들을 하나의 패키지로 묶는 작업들이 생기게 되었고, 결국 자바스크립트 비동기 방식의 꽃이라 불리는 Promise가 탄생하게 되었다.
PROMISE
Promise는 콜백 함수들로 이루어진 것이다.
원래 함수의 반환 값에 따라 경우의 수로 제어할 수 있다. 실행에 성공했을 경우 다음 함수로 진행한다던가, 실패했을 경우 에러 메세지를 얼럿 창으로 띄워준다든가 말이다. 이렇듯 Promise는 함수의 실행 시점을 기존 콜백 방식보다 간단하게 제어할 수 있는 자바스크립트 패키지다. 개발자가 원하는 함수의 실행결과에 따라 성공일 때 다음 작업을 진행할 수 있고, 실패일 때 작업을 멈추고 처음으로 되돌아가거나 오류 메세지를 사용자에게 띄워 줄 수 있다.
자바스크립트는 동기 방식의 언어이기 때문에 비동기 방식의 기본 문법은 없어야 함이 맞는 것 같다. 아무튼 콜백 함수를 더 작은 단위로 쪼개어보면 setTimeOut이나 setInterval과 같은 시점을 강제로 제어하는 것들로 이루어져 있다
- sync 문서를 작성하고 print시킨다. 다 프린트 되서 나올때까지 기다려서 확인. 그 다음 문서를 print시키고, 다 나올때까지 확인.(당연 절라 느림) (거기다 사람(application)이 계속 기달리고 있어야 함...시간 아깝죠?^^)
- async 문서를 print시키라고 마구 시킨다.(프린터야 죽어나든 말든..) 글구 사람(application)은 코딩작업을 마무리 하던가, 데브피아에 답변을 올리던가...일을 하다가 printer가 일이 끝나면, 삐~~(신호음)을 울려주고 그때서야 프린트가 잘 됐나 한번 봐준다^^ (사람(application)을 부릴땐 이렇게 시켜야 효율적으로 일하겠죠?^^) (실제로 쓰이고 있는 방식입니다.)
- non-blocking방식 프린트 시키고 딴짓하다가 프린트가 나오기 시작하면, 다 끝날때까지 기다림(sync보단 효율적이고, async보단 더 느리고) (recv함수를 쓰는 동안은 기다리니깐요)
덧. async가 네트워크 속도가 빠른 건 아닙니다(확인하고 보내는 시간이 없으니 조금 더 빠르긴 하지만, 프린트를 1000장을 시킬 때, 완료될때까지 걸리는 시간은 그렇게 차이가 안나죠. 문제는 사람(application)이 하루종일 기달리고 있느냐, 하루종일 딴 일하고 마지막에 확인만 해주느냐의 차이인 것이죠.
[ 2016.10.14 추가 내용 ]
Promise의 탐색 패턴은 Breadth First Search 이다.
실무에 자주 쓰이는 함수
setTimeout(function,millisecond)
setTimeout() 은 지정된 시간후 특정 코드를 실행시켜주는 메소드입니다. 뒤에서 다룰 setInterval() 과는 달리 setTimeout() 메소드를 사용하면 지정된 코드는 한번만 실행 됩니다.
setInterval(function,millisecond)clearTimeout(id)
setInterval()은 지정된 시간후 특정 자바스크립트 코드가 포함된 문자열을 반복하여 호출하는 메소드입니다. setTimeout() 이 지정 시간 후 한번만 호출하는데 비해, 이 메소드는 반복하여 호출 됩니다
clearINterval(id)
setInterval 함수로 시작된 타이머의 실행을 중단시킬 때 사용됩니다.
[출처] http://apple77y.tistory.com/11 & 이곳
비동기 로직의 사용처
자바스크립트에서 말하는 비동기로직이란 여러 개의 프레임으로 명령을 분산해 적재하는 것을 말한다.
명령을 개발자가 직접 적재하는 방법 : setTimeout, requestAnimationFrame, setInterval
시스템이 적절하게 적재하는 방법 : 이벤트 리스너 지정 등
명령을 프레임별로 다르게 실행시키는데는 중요한 네 가지 이유가 있습니다.
한 프레임에 너무 많은 명령을 적재하면 최초 1프레임의 렌더링이 늦어져 유저가 화면을 볼 수 있는 대기 시간이 길어진다.
애니메이션 처럼 시간자체를 지연하고 싶어 지연한다.
시스템이 수신하는 데이터(이벤트)는 시스템만 루프를 돌며 대기하고 스크립트는 발생한 후 통보를 받는 식으로 하여 부하를 줄일 수 있다.
한 프레임에서 실행되는 명령에는 시간 제약이 있으므로 무거운 로직은 여러 프레임에 걸쳐 처리하도록 해야한다.
[출처] http://www.bsidesoft.com/?p=399
JavaScript의 promise ajax
Promise는 문자 그대로 약속을 표현하는 자바스크립트 객체다. 약속은 지켜질 수 있고 물론 지켜지지 않을 수도 있다. 간단한 예를 들면, 선생님이 학생에게 숙제를 주었고 학생은 선생님께 숙제를 해오겠다고(미래의 언젠가) 약속(promise)했다. 이때 선생님은 다음과 같은 경우수를 생각할 수 있다.
학생이 숙제를 해온다고 약속하면 위 코드에서는 promise 객체를 반환한다고 생각하면 된다. 그리고 약속이 지켜질 때와 지켜지지 않을 때를 then 메서드를 이용해 정의하는데 지켜지면 첫 번째 콜백 함수가 호출되고 지켜지지 않으면 두 번째 콜백 함수가 호출된다. 이 처럼 promise 객체는 미래에 지켜지거나 지켜지지 않을 일을 객체로 표현했고 이 일들에 대한 처리를 then 메서드를 이용해 처리하는 것이다.
[출처] angular1에서의 promise와 defered
ajax와 promise
비동기 통신을 할 때 AJAX와 Promise라는 개념이 혼용되는 설명 글이 많은데 어떤 방식으로 그 두 개의 개념이 함께 활용되는지 살펴보자. 일단 AJAX는 앞에서 설명한 것처럼 서버와의 비동기 통신이다. 그리고 Promise는 AJAX의 상태에 따라 분기 처리를 할 수 있게 서포트해주는 객체다. 예를 들어 연속되는 프로세스 A -> B 가 있다고 가정하자. 각각의 프로세스는 서버와 통신을 하며, 후행 프로세스(B)는 선행 프로세스(A)가 반드시 성공됐다는 보장이 되어야 실행이 되어야 한다. 각각의 프로세스는 AJAX로 서버와 통신을 한 뒤, 상태 값을 리턴받는다. 리턴되는 값은 경우에 따라서 데이터가 될 수도 있고 에러코드가 될 수도 있다. A 프로세스가 성공되었을 때는 "성공"이라는 것을 리턴해줘서 B가 실행될 수 있게끔 해줘야 되는데 이때 필요한 것이 Promise다. 물론 AJAX에서 모든 케이스를 잡고 콜백 중첩을 활용해서 처리할 수 있지만, 예전에 설명한 대로 콜백이 여러 개 중첩되면 유지 보수를 하기에 굉장히 불편한 코드가 된다.
따라서 AJAX 통신을 할 때 보다 깔끔한 코드 관리를 위해 Promise를 활용한다. 이 객체에 있는 resolve, reject등을 활용하여 상태값에 따른 분기 처리를 할 수 있다. 5버전의 자바스크립트에서는 Promise가 지원되지 않아서 외부 라이브러리를 사용해야 하는데, 최근에 발표된 6버전에서는 Promise가 지원되기 때문에 앞으로는 기본적으로 지원되는 Promise를 활용할 수 있게 되었다. 하지만 브라우저 별 호환성 문제로 기본 메소드 사용은 사용이 불가능 할 것 같다.
[출처] http://apple77y.tistory.com/40
http.get 이 return 하는 observable은 angular 2가 아니라 rxjs에 있는 것이다.
rxjs는 systemjs.config.js에 있다.
rxjs document?
https://github.com/ReactiveX/RxJS/blob/master/MIGRATION.md
javascript의 promise defer
angular에서 ajax // observable
http://www.syntaxsuccess.com/viewarticle/angular-2.0-and-http
angular에서 observable, asyncronized
http://chariotsolutions.com/blog/post/angular2-observables-http-separating-services-components/
'javascript & jQuery' 카테고리의 다른 글
각 브라우저별 특징 (0) | 2016.09.12 |
---|---|
jQuery 요소 찾기 (0) | 2016.09.09 |
json (0) | 2016.08.22 |
RESTFUL(Representational Safe Transfer) (0) | 2016.08.19 |
HTTP 통신 VS Socket 통신 (0) | 2016.08.18 |