웹 브라우저?
🔻 웹 브라우저?
: 서버에서 받아온 HTML, CSS, JS를 실행시켜주는 프로그램이다.
브라우저는 자바스크립트를 실행하는 과정이 있다.
브라우저는 C++이라는 언어로 코드가 짜져있는데, 브라우저는 실행해야할 자바스크립트 코드를 발견하면
C++ 언어로 만들어둔 stack에 넣어서 돌린다.
stack은 다 집어넣고 맨 윗줄부터 하나하나 실행시키는 공간이다.
하지만, 서버로의 ajax 요청, eventlistener, setTImeout 이런 코드들은 코드를 처리하기까지 시간이 오래걸린다.
그래서 이런코드들은 stack에 쌓아서 실행하지않고, Queue라는 곳에 집어넣고 기다렸다가
stack이 비어있을 때 차례로 Queue에서 stack으로 집어넣어서 실행해준다.
따라서, stack을 바쁘게 만들면 setTimeout 이런 코드들은 실행이 불가능하다.
🤷🏻♀️ 시간이 오래 걸리는 작업을 꼭 해야한다면 ?
1. setTimeout을 이용한다.
작업을 0초마다 쪼개서 실행하게 한다. 그러면 0초마다 Queue로 보내기때문에 그 사이사이 사용자의
eventlistener이런 코드가 실행가능하게된다. ( 0초로 실행해도 4ms로 동작한다. 최소시간이 4ms )
2. web worker를 이용한다.
다른 js파일을 이용해서 오래걸리는 작업을 따로 작동시키고 그게 완료되면 값을 가져오라고 명령한다.
(메인 js 파일)
var myWorker = new Worker('worker.js');
w.onmessage = function(e){
console.log(e.data) //이러면 1 나올듯
};
(worker.js 파일)
var i = 0;
postMessage(i + 1); //postMessage라는 특별한 함수가 있음
이런식으로 셋팅하면 worker.js에서 작업완료 시 postMessage() 이렇게 실행하면 다른 파일로 완료된 결과값을 전달해줄 수 있다.
이러면 stack이 바빠지지않는다.
동기? 비동기?
🤷🏻♀️ 동기식 처리?
: 동기식 처리는 한번에 코드 한줄씩 차례로 실행되는 것이다.
위에서 설명된 웹브라우저의 stack이라는 코드실행공간에서 자바스크립트는 동기적으로 처리된다.
but, 비동기처리 (asynchronous)가되는 특수한 함수들 때문에 가끔 비동기적 실행이 된다.
console.log(1);
setTimeout(()=>{ console.log(2) }, 1000 };
console.log(3);
//출력
1
3
2
setTimeout()이라는 함수는 Queue로 들어가서 제쳐두고, 다른 코드부터 실행되므로 1-3-2순서로 출력된다.
이런 처리방식을 비동기라고 한다. ( 오래걸리는 작업이 있으면 제껴두고 다른거부터 처리 )
자바스크립트 언어자체는 동기식 처리가 되지만,
Web API와 연관된 특수한 함수들을 쓰면 작업이 오래걸리 때 다른것부터 실행이 가능하다.
( Web API에 오래걸리는 작업들을 넣어놓고 빨리 처리되는 함수들 먼저 실행한다. )
Callback함수
🤷🏻♀️ 비동기상황에서 순차적으로 코드를 실행하고 싶다면?
: 콜백함수를 활용한다.
콜백함수는 간단하게 함수안에 들어가는 함수를 전부 콜백함수라 생각할 수 있다.
function 첫째함수 () {}
function 둘째함수 () {}
//순서대로 실행하고 싶을때 setTimeout같은 함수가 있으면 이런식으로 실행시 실패한다.
첫째함수()
둘째함수()
//이럴때 콜백함수로 실행하면 순차적으로 실행이 가능하다.
첫째함수(둘째함수)
callback 함수
function 첫째함수(둘째) {
console.log(1);
둘째();
}
function 둘째함수(){
console.log(2);
}
첫째함수(둘째함수);
callback 함수의 문제점
- 순차적으로 실행하고싶은 코드가 여러개라면 코드가 지저분해진다.
이러한 문제점을 개선한 것이 promise.
첫째함수(function(){
둘째함수(function() {
셋째함수(function() {
})
})
});
Promise
Promise
: 자바스크립트의 새로운 기능이라기보다는 코드/함수 디자인 패턴이다.
(동기를 비동기로 만들어주는 코드가 아니고, 디자인 패턴)
let 프로미스 = new Promise(성공, 실패) {
let 어려운 연산 = 1+1;
//연산 후 실행하고 싶은 코드를 적는다. 성공() 적으면 .then에 있는, 실패() 적으면 .catch
//성공()
//실패()
};
프로미스
.then(()=> {}) //성공시 실행되는 코드
.catch(()=> {}) //실패시 실행되는 코드
new Promise()로 생성된 변수를 콘솔창에 출력해보면 현재상태를 알 수 있다.
[ 3가지 상태 ]
성공/실패 판정 전에는 pending
성공 후에는 resolved
실패 후에는 rejected
프로미스안에 콜백함수 실행
성공 했을 때 then() 함수내의 코드를 실행
실패했을 경우에는 catch( ) 함수내의 코드를 실행한다. (callback함수와 다른점)
콜백대신 쓰는이유?
- 콜백보다 코드가 깔끔하다.
- 성공/실패의 경우 각각 다른 코드가 실행가능하다.
[예시]
> setTimeout 예시
1초후에 성공하는 promise - 성공시 특정코드 실행
let 프로미스 = new Promise(function (성공, 실패) {
setTimeout(() => {
성공();
}, 1000);
});
프로미스
.then(() => {
console.log("success");
})
.catch(() => {
console.log("fail");
});
async / await
async를 사용하면 promise object가 저절로 생긴다.
( async는 함수 앞에만 붙일 수 있다. )
async function 더하기(){
return 1 + 1
}
//async를 붙였으니까 then 사용 가능
//return 결과값 then 함수에서 파라미터로 넣어주면 사용가능
더하기().then(function(결과){
console.log(결과)
});
then 대신 await를 async function 안에서 쓸 수 있다.
await를 붙여주는 함수가 다 끝날 때 까지 기다려준다.
async function 더하기() {
let 연산 = new Promise((성공, 실패) => {
let 결과 = 1 + 1;
성공(100);
});
let 결과 = await 연산 //연산 promise를 기다린다음에 완료되면 결과를 변수에 담아라.
console.log(결과)
//아래의 promise코드와 위의 await는 같은 역할을 한다.
//promise.then (()=> {
//console.log('결과')
}
더하기()
await는 실패하면 에러가 나고 코드가 멈춘다.
promise가 실패할 경우 코드실행을 멈추고 싶지 않으면 try catch를 사용한다.
try{}안의 코드가 에러나고 멈출경우, 대신 catch{}내부의 코드를 실행한다.
try { 이걸해보고 에러나면 } catch { 이걸 실행해 }
async function 연산 () {
let 프로미스 = new Promise ((성공, 실패)=> {
let 연산 = 1+1;
성공(연산)
});
try {
let 결과 = await 프로미스;
console.log(결과);
} catch {
console.log('실패')
}
}
'Archive' 카테고리의 다른 글
[TS] declare / d.ts / index signatures (0) | 2022.01.13 |
---|---|
[TS] React (0) | 2022.01.12 |
[GIT] Github 잔디 안심어지는 현상 (0) | 2022.01.05 |
[JS] getter,setter / import,export (0) | 2022.01.05 |
[TS] Private / Static / Generic 등 (0) | 2022.01.05 |