자바스크립트는 single threaded language
➡️ 한번에 코드 하나밖에 실행 못함
➡️ 병렬 불가
자바스크립트를 실행하는 웹브라우저는 stack이라는 코드 실행 공간이 있는데 거기서 코드를 한줄한줄 차례로 실행한다
오래걸리는 작업이 있으면 다른 것부터 처리하는 방식
➡️ setTimeout , 이벤트리스너, ajax 함수 등등으로
웹 브라우저 덕분에 가능
만약 setTimeout 같은 코드를 만나면 잠시 Web API 로 옮겨서 대기시킨다
그리고 대기시간이 끝나고 setTimeout이 완료되면 대기실에서 코드를 꺼내서 실행시킨다
만약 파이썬으로 시간 차 출력을 하면
print(1)
time.sleep(1)
print(2)
하지만 자바스크립트에서는
console.log(1);
setTimeout(function(){}, 1000);
console.log(2);
자바스크립트는 실행까지 조금 시간이 걸리는 함수를 발견하면 제쳐두고 다른코드부터 실행하려고 한다
➡️ 이것이 비동기 이다
📢 콜백함수 사용
왼쪽 요소가 끝나길 기다렸다가 실행시키고 싶은 코드들 작성
console.log(1);
setTimeout(function(){console.log(2)}, 1000);
function one(){
console.log(1)
}
function two(){
console.log(2)
}
one();
two();
만약 첫쨰함수 실행 후 둘째함수를 실행시키고 싶다면?
파이썬으로 코드짠다면 이게 맞지만 자바스크립트는 비동기라는 특수성으로 인해 이렇게 쓴다고 순차적으로 실행하는걸 보장하진 않는다
(첫째함수가 setTimeout 등 Web API 대기실로 보내는 코드라면 나중에 실행될 수 있기 때문)
그렇다면 콜백함수로 만들면 된다
첫째함수(둘째함수)
function one(func) {
console.log(1);
func();
}
function two() {
console.log(2);
}
one(two);
이렇게 미리 만들어놓은 함수를 넣어도 되고
one(function(){
console.log(2)
}):
함수선언문을 직접 파라미터 자리에 입력해도 된다
!
(함수 파라미터에 들어간 함수가 바로 콜백함수)
첫째함수(function(){
둘째함수(function(){
셋째함수(function(){
어쩌구..
});
});
}):
➡️ 콜백 대신 Promise 사용
첫째함수().then(function(){
그 담에 실행할거
}).then(function(){
그 담에 실행할거
});
콜백함수와 차이
- 코드 예쁘게 작성 가능
- 성공/실패의 경우에 맞춰 다른 코드 작성 가능
var promise = new Promise(function (resolve, reject) {
var math = 1 + 1;
resolve(math);
});
promise
.then(function (res) {
console.log("성공" + res);
})
.catch(function () {
console.log("실패");
});
new Promise()
로 생성된 변수를 통해 현재 상태 알 수 있음promise
는 동기 -> 비동기로 바꿔주는 것이 아니다원래 자바스크립트는 평상시엔 동기적으로 실행이 되며 비동기 실행을 지원하는 특수한 함수들 덕분에 가끔 비동기적 실행이 될 뿐이다
var imgloading = new Promise(function (resolve, reject) {
$("#test").load(function () {
resolve(); //성공하면 성공함수 실행
});
$("#test").error(function () {
reject(); //실패하면 실패함수 실행
});
});
imgloading
.then(function () {
console.log("성공");
})
.catch(function () {
console.log("실패");
});
프로미스 안에서는 성공( ), 실패( )가 실행되는 경우의 수를 만들어주면 되고 이제 .then( ) .catch( )를 이용해서 성공/실패시 특정 코드들을 실행한다
jquery로 ajax 요청하는 방법
$.ajax({ type : 'GET', url : 'URL 경로' }) //or $.get('URL 경로')
var loading = new Promise(function (resolve, reject) {
$.get("https://codingapple1.github.io/hello.txt").done(function (data) {
resolve(data);
});
});
loading
.then(function (res) {
console.log("성공 메세지 : " + res);
})
done
으로 url data를 파라미터로 받아오고 성공 시reslove
를 통해넘겨준다. 그러면loading
이 성공했을 때의 콜백함수에resolve
에서 넘겨준 값을 파라미터로 받아와서 실행하게 된다
var promise = new Promise(function (resolve, reject) {
$.get("https://codingapple1.github.io/hello.txt").done((data) => {
resolve(data);
});
});
promise
.then(function (res) {
console.log("성공 메세지 : " + res);
// 새로운 promise 객체
var promise2 = new Promise(function (resolve, reject) {
$.get("https://codingapple1.github.io/hello.txt").done((data) => {
resolve(data);
});
});
return promise2;
})
.then((res) => {
console.log(res);
});
- 첫프로미스가 성공하면 then() 안의 코드를 실행시켜줍니다.
- 근데 거기 안에는 프로미스2가 있습니다. 프로미스2가 성공하면
- 뒤에 있는 then() 안의 코드를 실행시켜줍니다.