- 자바스크립트 프로그램은 여러 개의 덩이(chunk)로 이루어진다.
- 덩이는 지금 실행하는 덩이와 나중에 실행할 덩이로 구성된다.
- 가장 일반적인 프로그램 덩이 단위는 함수이다.
- 아래의 Ajax 코드를 보면 ajax() 함수의 결과값을 변수의 담을 수 없는 것을 알 수 있다.
ajax 함수가 응답받을 때까지 흐름을 중단했다면 문제가 없었을 거다.
const data = ajax('http://some.url.1'); console.log(data); // ajax의 결과는 변수에 담지 못한다.
- 지금부터 나중까지 기다리는 좋은 방법은 콜백 함수를 이용하는 것이다.
예를 들어 이벤트가 트리거 되면 전달된 콜백 함수를 실행하는 것이다.
function now() { console.log("now"); } function later() { console.log("later); } now() setTimeout( later, 1000 );
- 물론 동기적으로 비동기 실행 결과를 기다릴 수 있지만 ui가 멈추거나 다른 작업이 중단되는 불상사가 발생하게 될 것이다.
- console.log 메서드는 I/O 비동기성으로 출력이 지연될 때가 있다.
우리는 평소 결과가 {index:1}로 예상을 하지만 가끔 지연이 되면 { index:2} 로 나올 수 도 있다.
var a = { index: 1, }; // 나중에 console.log(a); // ?? // 더 나중 a.index++;
- 이벤트 루프는 여러 프로그램 덩이를 매 순간 한 번씩 엔진을 실행시키는 장치이다.
- 사실 자바스크립트 시간관념을 가지고 있지 않고 임의의 자바스크립트 코드 조각을 주는 대로 처리하는 실행기일 뿐이고 이벤트를 스케줄링하는 일은 엔진을 감싸고 있는 주변 환경의 몫이다.
- 예를 들어 서버에서 데이터를 조회하기 요청을 하면 브라우저가 네트워크를 통해 리스닝을 하고 데이터가 도착하면 코드를 다시 실행하는 것이다.
- 비동기와 병렬의 차이
- 비동기: 비동기는 지금과 나중 사이의 간극에 관한 용어
- 병렬: 동시에 일어나는 일에 관한 용어
- 프로세스와 스레드는 가장 많이 쓰이는 병렬컴퓨팅도구이다.
- 단일 스레드와 달리 하나의 프로그램에서 여러 스레드를 처리하는 병렬 시스템에선 예상치 못한 일이 발생할 수 있다.
위의 코드에서는 foo가 먼저 실행이 될 수 도 있고 bar가 먼저 실행이 될 수 도 있다. 위와 같이 두 쓰레드가 병렬 상태로 실행되는 스레드 프로그래밍은 결과를 예상하기 힘들어 진다.
let a = 20; function foo() { a = a + 1; } function bar() { a = a * 2; } ajax('http://some.url.1', foo); ajax('http://some.url.2', bar);
- 자바스크립트에서 함수가 한번 실행되면 그 함수 전체 실행이 끝난 이후에 다음 함수가 실행된다. 이를 완전-실행이라 한다.
- 함수 순서에 따른 비결정성은 스레드와 달리 문의 수준까지는 아니기에 스레드보단 결정적이라고 볼 수 있다.
- 자바스크립트에서 함수 순서에 따른 비결정성을 경합 조건이라고 표현한다.
무한스크롤을 구현 하는 과정에서 스크롤을 하는 onscroll 작업과 데이터를 가져오는 두 비동기성 작업이 있을 때 두 작업이 동시에 발생 하는 경우가 있을 것이다. 자바스크립트는 이러한 상황을 동시에 처리하지 않고 이벤트 루프 큐에서 차례대로 실행이 된다.
두 작업이 언제 실행될진 모르지만 서로 상호작용이 일나지 않다면 비결정성은 완벽하게 수용 가능하다.
- 직접 조건을 정해주어 경합 조건에 의한 비결정성을 해소할 수 있다.
- 예를 들어 ajax를 사용하는 경우에서 URL 별로 실행 방식을 지정해 주게 되면 URL 간의 상호작용을 예상하기 좀 더 수월해질 것이다.
- 또는 조건을 주어 두 작업이 모두 끝났을 때 실행이 되는 조건을 걸어 줄 수 있다.
- 협동적 동시성은 동시성을 조정하는 방안이며 오래 걸리는 프로세스를 여러 단계/배치로 쪼개어 다른 동시 작업이 각자 작업을 이벤트 루프 큐에 인터리빙 하도록 하는 것이 목표이다.
- 예를 들어 큰 데이터를 매핑할때 개수 제한을 두어 제한된 개수 실행 후 다른 작업 진행하고 다시 제한된 개수를 실행하는 과정을 반복한다.
- 잡 큐는 이벤트 루프 큐에 새롭게 도입된 념이다.
- 잡 큐는 이벤트 루프 큐에서 매 틱의 끝자락에 매달려있는 큐이다. 다른 작업들보다 우선하여 처리한다고 생각하면 된다.
- 자바스크립트 엔진이 문을 위에서 아래로 순서대로 실행할 것 이라 생각하기 쉽다. 하지만 자바스크립트 엔진은 소스 코드를 결과가 변경되지 않는 선에서(부수효과가 없는 선에서) 코드를 최적화 하기에 소스코드의 순서와 컴파일 이후의 순서는 관계가 없다.