자바스크립트는 싱글스레드
그래서 하나의 일을 할 때 하나밖에 못함 → 그런데 그 하나의 일이 오래 걸리는 일이면?
→ 다른 작업들은 그 오래걸리는 일이 끝날 때 까지 오~~래 기다려야한다.
⇒ 이러한 문제점을 해결하기 위해서 비동기로 어떠한 일을 수행하게 된다.
만약 비동기 요청이 여러 개 있을 때 하나의 요청이 다른 요청의 결과에 의존한다면?
위의 소스코드에서 처럼 둘 다 비동기 요청을 보내는데 두 번째 요청에서 첫 번째 요청의 결과가 필요할 수가 있다.
하지만, 둘 다 병렬적으로 요청을 보내기 때문에 response1을 가지기 전에 두 번째 요청이 보내지게 된다.
⇒ 이 문제를 어떻게 해결할까?
Callback 함수, Promise, Async Await 를 이용하는 세 가지 방법이 있다.
Callback 콜백 함수
특정 함수에 매개변수로 전달된 함수를 의미함. 그리고 그 콜백함수는 함수를 전달받은 함수 안에서 호출됨
- 콜백 사용의 단점
- 소스코드를 보는 데 가독성이 떨어짐
- 에러 처리를 한다면 모든 콜백에서 각각 에러 핸들링을 해주어야 함
Promise
Promise 객체는 new 키워드와 생성자를 통해 만든다.
new Promise(resolve, reject)
생성자는 매개변수로 “실행함수”를 받는다. 이 함수는 매개변수로 두 가지 함수를 받아야 한다.
- 첫번째 함수 resolve : 비동기 작업을 성공적으로 완료해 결과를 값으로 반환할 때 호출
- 두번째 함수 reject : 작업이 실패하여 오류의 원인을 반환할 때 호출.
⇒ 즉, 성공시 resolve, 실패시 reject 이다.
const myFirstPromise = new Promise((resolve, reject) => {
// Do something asynchronous which eventually calls either:
//
// resolve(someValue); // if the operation is successful
// or
// reject("failure reason"); // if there is an error
});
- Promise 는 자바스크립트 비동기 처리에 사용되는 객체
- Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과값을 나타낸다.
let myFirstPromise = new Promise((resolve, reject) => {
// 우리가 수행한 비동기 작업이 성공한 경우 resolve(...)를 호출하고,
// 실패한 경우 reject(...)를 호출합니다.
// 이 예제에서는 setTimeout()을 사용해 비동기 코드를 흉내냅니다.
// 실제로는 여기서 XHR이나 HTML5 API를 사용할 것입니다.
setTimeout(function() {
resolve("성공!"); // 와! 문제 없음!
}, 250);
});
myFirstPromise.then((successMessage) => {
// successMessage는 위에서 resolve(...) 호출에 제공한 값입니다.
// 문자열이어야 하는 법은 없지만, 위에서 문자열을 줬으니 아마 문자열일 겁니다.
console.log("와! " + successMessage);
});
위의 기본 코드를 바탕으로 작성해보면, 아래와 같이 적을 수 있는데
function fetchData() {
return new Promise((resolve, reject) => {
const success = true; // 성공 여부를 나타내는 변수
if (success) {
resolve('성공'); // 성공일 때 호출
} else {
reject('실패'); // 실패일 때 호출
}
});
}
fetchData()
.then(function(result) {
console.log(result); // 성공
})
.then(function(error) {
console.log(error); // undifined
});
⇒ 그런데 실제로는 에러 처리시 then 하는게 아니라 아래의 사진처럼 catch로 처리한다.
Promise는 다음 중 하나의 상태를 가진다.
대기(pending) : 비동기 처리 로직이 아직 완료되지 않은 상태
- 아직 result는 없어욤
이행(fullfilled) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
거부(rejected) : 비동기 처리가 실패하거나 오류가 발생한 상태
대기 중인 프로미스는 값과 함께 이행할 수도, 어떤 이유(오류)로 인해 거부될 수도 있다.
- 이행이나 거부될 때, Promise의 then 메서드에 의해 대기열 (큐)에 추가된 처리기들이 호출된다.
- 이미 이행했거나 거부된 프로미스에 처리기를 연결해도 호출됨. → 비동기 연산과 처리기 연결 사이에 경합 조건은 없다.
Promise.all()
순회 가능한 객체에 주어진 모든 프로미스가 이행한 후, 혹은 프로미스가 주어지지 않았을 때 이행하는 Promise 를 반환한다. 주어진 프로미스중 하나가 거부하는 경우, 첫 번째로 거절한 프로미스의 이유를 사용해 자신도 거부한다.
arrays안에 순회 가능한 객체를 넣어줌. (배열과 같은)
세개가 다 이행 (fullfill)이 된 후 한번에 반환 (하나라도 reject되면 reject 반환)
Promise.race()
Promise 객체를 반환하는데, iterable 안에 있는 프로미스 중에 가장 먼저 완료된 것의 결과값으로 그대로 이행하거나 거부한다.
먼저 완료된것의 결과값을 보여줌.
Async / Await
문법적으로 훨씬 깔끔해지게 만든건데용
- 비동기 코드지만 마치 동기 코드처럼 보인다
- 하나 끝나면 기다렸다 하게 하고.. 이렇게
- Promise에 then 메서드를 체인 형식으로 호출하는것 보다 가독성이 좋다
- await는 async 내부 함수에서만 사용할 수 있다.
- 동기식 코드에서 쓰는 try..catch 구문을 async/await 구조에서 사용할 수 있다.
'☁️ 구름 X kakao DeepDive > ☁️ HTML CSS JS' 카테고리의 다른 글
[JavaScript] Iterator(반복기) & Generator(생성기) (0) | 2025.01.09 |
---|---|
[JavaScript] Symbol (0) | 2025.01.09 |
[JavaScript] Prototype 그리고 ES6 Classes, Sub Class(Inheritance), super()란? (0) | 2025.01.09 |
[JavaScript] OOP, 다형성 (0) | 2025.01.09 |
[JavaScript] 조건부 삼항 연산자 (0) | 2025.01.09 |