콜백함수로 비동기 처리를 하는것의 단점을 보완하기 위해 등장하게됨.
▫️ promis 생성자 함수는 비동기 처리를 수행할 콜백함수를 인수로 받는다, 그리고 이 콜백함수는 비동기 처리가 성공하면 호출할 resolve와 비동기 처리가 실패하면 호출할 reject함수를 인수로 전달 받음
▫️ 프로미스는 비동기 처리 상태와 처리 결과를 관리하는 객체
const test = new Promise((resolve, reject) => {
const 성공 = true; // 성공 여부를 설정 (true: 성공, false: 실패)
if (성공) {
resolve('작업 성공!');
} else {
reject('작업 실패!');
}
});
fulfilled
rejected
settled상태
fulfilled or rejected 상태
실패, 성공에 관련없이 pending 이 아닌 상태로, 비동기가 처리가 수행된 상태를 의미, setted 상태가 되면 더는 다른 상태로 변화할수없다.
▫️프로미스의 상태가 pending 에서 변화하면, 결과값을 가지고 동작을 해야한다. 이를 위해 프로미스는 catch, then, finally 메소드를 제공한다.
▫️후속처리 메소드에 인수로 전달할 콜백함수가 선택적으로 호출된다. 그리고 그 콜백함수에 프로미스의 처리 결과가 인수로 전달된다.
모든 후속 처리 프로미스는 프로미스를 반환하며, 비동기로 동작한다.
- then
▫️두개의 콜백함수를 인수로 전달받는다.
▫️첫번째 함수 : resolve가 호출되었을때 처,. 이때 비동기 처리 결과를 인수로 전달 받는다
▫️두번째 함수 : reject가 호출되었을때 처리, 에러를 인수로 전달받음
```jsx
const test = new Promise((resolve, reject) => {
const 성공 = true; // 성공 여부를 설정 (true: 성공, false: 실패)
if (성공) {
resolve('작업 성공!');
} else {
reject('작업 실패!');
}
});
test.then(
(result) => {
// 첫 번째 콜백: 성공 시 실행
console.log(result);
},
(error) => {
// 두 번째 콜백: 실패 시 실행
console.error(error);
}
);
```
catch
▫️ 한개의 콜백함수를 인수로 전달받음
▫️ 프로미스가 rejected 상태인경우에만 호출됨
finally
▫️한개의 콜백 함수를 인수로 전달 , 성공이나 실패와 상관없이 무조건 한번 호출,
▫️ then 메소드의 두번째 콜백으로 에러 처리가 가능하나, 첫번째 콜백 에서의 에러는 잡아내지 못하고, 가독성이 부족
▫️ catch 메서드를 then 메서드 이후에 호출하면 비동기 처리에서 발생한 에러, then 메소드 에서 발생한 에러까지 모두 캐치하므로, 이방법을 권장한다.
const test = new Promise((resolve, reject) => {
const 성공 = true; // 성공 여부를 설정 (true: 성공, false: 실패)
if (성공) {
resolve('작업 성공!');
} else {
reject('작업 실패!');
}
});
test.then(
(result) => {
console.log('성공:', result);
})
.catch((error) => {
console.error('실패:', error);
});
promise 인스턴스에서 호출하는것이 아니라, promise 객체에서 호출하는 메소드
▫️ resolve : 메소드에 이미 존재하는 값을 래핑하여 프로미스를 생성하기 위해 사용
비동기 작업 없이 즉시 성공 상태의 promise 를 반환할때 유용
▫️ reject : 인수로 전달 받은 값을 reject하는 프로미스 생성
특정 상황에서 즉시 실패 상태의 promise를 반환할때 사용
여러 비동기 작업을 동시에 실행하고, 모든 작업이 완료된 후에 처리가 필요할 때 활용
- 여러개의 비동기 처리를 모두 병렬 처리할때 사용.
- 프로미스를 요소로 갖는 배열등의 이터러블 을 인수로 전달
- 모든 요소가 fulfilled 상태가 되면 모든 처리 결과를 배열에 저장해 새로운 프로미스를 반환
- 하나라도 reject 상태가 되면 즉시 종료함
- 인수로 전달받은 이터러블 요소가 프로미스가 아닌경우 promise. resolve 메소드를 통해 프로미스로 래핑함
모든 Promise의 상태를 확인하고 싶을 때 활용
- 프로미스를 요소로 갖는 이터러블을 인수로 전달 받는다. 전달받은 프로미스가 모두 settled 상태면 처리 결과를 배열로 반환
- 프로미스의 처리 결과를 나타내는 객체의 배열을 갖는데, fulfilled 상태인경우에는 상태값인 status와 처리 결과값인value 프로퍼티를 갖는다
- reject 상태인경우 처리 상태를 나타내는 status, 에러를 나타내는 reason 프로퍼티를 가진다.
▫️마이크로 태스크 큐에는 프로미스의 후속처리 메소드의 콜백함수가 일시 저장됨.
▫️그 외의 비동기 함수의 콜백함수나 이벤트 핸들러는 태스크 큐에 일시 저장됨.
▫️ 마이크로 태스크 큐는 태스크 큐보다 우선순위가 높음
- 이벤트 루프의 동작
- 호출스택이 비었는지 지속적으로 확인
- 호출 스택이 비게 되면 제일 먼저 마이크로 태스크 큐를 확인하고 가장 오래된 태스크부터 꺼내서 호출스택으로 전달해 주는데, 이걸 마이크로태스크 큐가 다 빌때까지 수행
- 모든 마이크로태스크가 처리된 직후, 렌더링 작업이 필요하면 렌더링을 수행
- 매크로 태스크 큐를 확인
- 매크로 태스크 큐에서 가장 오래된 태스크 하나를 꺼내 호출 스택에 전달
- 위를 반복

▫️
fetch함수는 기본적으로 Promise를 반환, 따라서 별도로new Promise()를 생성할 필요 없이 바로 체이닝(.then,.catch)을 사용하여 비동기 처리가 가능 한 JavaScript API
▫️위의 명시적으로 promise 를 생성하는것보다 더 권장되는 방식▫️http 응답을 나타내는 response 객체를 래핑한 프로미스를 반환하므로 후속 처리 메소드 then 을 통해 프로미스가 resolve 한 response 객체를 전달 받을 수 있다.
const test = new Promise((resolve, reject) => {
const 성공 = true; // 성공 여부를 설정 (true: 성공, false: 실패)
if (성공) {
resolve('작업 성공!');
} else {
reject('작업 실패!');
}
});
test.then(
(result) => {
console.log('성공:', result);
})
.catch((error) => {
console.error('실패:', error);
});
axios 모든 에러를 reject 하는 프로미스를 반환, 따라서 모든 에러를 catch에서 처리할수 있어 편리함. 또한 axios는 인터셉터, 요청 설정등 fetch 보다 다양한 기능을 지원
명시적으로 promise 를 생성하는 것은 이벤트 기반 작업, 특정 조건에서 비동기 작업 제어, 타임아웃 또는 취소 처리와 같은 고급 비동기 로직에서 유용함.
그러나 일반적인 비동기 작업에서는 async/await 를 사용하는 것이 훨씬 간단하고 가독성이 측면에서 좋음 따라서 두 방법을 적절히 혼합해서 사용하는 것이 가장 효율적
promise 객체를 직접 생성하면 resolve와 reject를 명시적으로 호출할 수 있기 때문에, 특정 조건이나 시점에 비동기 처리를 제어할 때 유용
후속 처리 메서드는 비동기 작업이 끝난 뒤 결과를 처리하기 위한 도구, 하지만 명시적으로 promise 를 생성하는 건 비동기 작업의 완료를 개발자가 원하는 시점에서 제어해야 할 때 필요함
function test(ms) {
return new Promise((resolve) => {
setTimeout(() => {
;//setTimeout으로 지정한 시간후에 비동기 완료
console.log('작업완료')
resolve();
}, ms);
});
}
// 사용
test(1000).then(() => console.log("작업 완료"));
function test(url, timeout) {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
reject(new Error("timed out"));
}, timeout);
fetch(url)
.then((response) => {
clearTimeout(timer);//timeOut을 꼭 취소해야한다.
resolve(response);
})
.catch((error) => {
clearTimeout(timer);
reject(error);
});
});
}
// 사용
test("https://api.example.com", 3000)
.then((response) => console.log(response))
.catch((error) => console.error("에러 발생", error));
fetch 함수와 Promise 체이닝 fetch 함수는 기본적으로 Promise를 반환, 따라서 별도로 new Promise()를 생성할 필요 없이 바로 체이닝(.then, .catch)을 사용하여 비동기 처리가 가능
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then((response) => {
if (!response.ok) {
throw new Error('HTTP 오류!');
}
return response.json(); // 응답 데이터를 JSON으로 변환
})
.then((data) => {
console.log('데이터:', data); // 성공적으로 데이터를 처리
})
.catch((error) => {
console.error('에러 발생:', error.message); // 에러 처리
});
new Promise를 생성하는 방식fetch는 이미 Promise를 반환하기 때문에 new Promise()로 감싸는 것은 불필요한 경우가 많음.. 하지만 명시적으로 Promise를 생성하면 더 세부적인 비동기 작업 흐름을 정의하거나, 조건에 따라 resolve나 reject를 호출할 수 있음.
const fetchWithPromise = () => {
return new Promise((resolve, reject) => {
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then((response) => {
if (!response.ok) {
reject(new Error('HTTP 오류!')); // 명시적으로 reject 호출
} else {
response.json().then(resolve); // 명시적으로 resolve 호출
}
})
.catch((error) => {
reject(error); // 네트워크 에러 처리
});
});
};
// 사용 예
fetchWithPromise()
.then((data) => {
console.log('데이터:', data);
})
.catch((error) => {
console.error('에러 발생:', error.message);
});

fetch 체이닝을 사용하는 것이 더 권장
fetch 자체가 Promise를 반환하므로, 추가적으로 new Promise를 생성할 필요가 없음new Promise를 사용하는 경우특정 상황에서 resolve/reject 호출을 세밀하게 제어해야 하거나, fetch와 다른 비동기 로직을 결합해야 할 때 사용
예: 파일 읽기, 여러 비동기 작업을 묶어서 처리할 때.
XMLHttpRequest(XHR)는 비동기 데이터 요청을 웹 서버에 보낼 때 사용되는 자바스크립트 객체입니다. 브라우저에서 AJAX(Asynchronous JavaScript and XML) 요청을 보낼 수 있게 해주는 기본 도구 중 하나
XMLHttpRequest는 브라우저가 제공하는 API 중 하나이며, 오늘날 fetch API와 같은 최신 기술이 많이 사용되지만, 여전히 일부 구형 프로젝트나 특정 상황에서 사용
비동기 통신 지원:
HTTP 요청 전송:
다양한 데이터 형식 지원:
- XML, JSON, HTML, 텍스트 등 다양한 형식으로 데이터를 주고받을 수 있음
예제
const xhr = new XMLHttpRequest(); // XMLHttpRequest 객체 생성
xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true); // 요청 초기화
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) { // 요청이 완료되었을 때 (readyState === 4)
if (xhr.status === 200) { // HTTP 상태 코드가 200일 때 (성공)
console.log('응답 데이터:', xhr.responseText);
} else {
console.error('오류 발생:', xhr.status);
}
}
};
xhr.send(); // 요청 전송
### 코드 설명
1. **`new XMLHttpRequest()`**: XHR 객체 생성.
2. **`open(method, url, async)`**: 요청 초기화.
- `method`: HTTP 메서드(GET, POST 등).
- `url`: 요청할 서버 주소.
- `async`: 비동기 여부(`true`가 기본).
3. **`onreadystatechange`**: 요청 상태가 변경될 때 호출될 콜백 함수.
- `readyState`: 요청 상태(0~4).
- `0`: 요청 초기화되지 않음.
- `1`: 연결 설정 완료.
- `2`: 요청 수신됨.
- `3`: 요청 처리 중.
- `4`: 요청 완료.
- `status`: HTTP 상태 코드(예: `200`은 성공, `404`는 페이지 없음).
4. **`send()`**: 요청 전송.
### **XMLHttpRequest와 fetch의 차이점**

### **결론**
- `XMLHttpRequest`는 **구형 방식**으로, 현대적인 코드에서는 잘 사용되지 않음.
- 대신 **`fetch` API**가 더 권장되며, 비동기 작업에서는 `Promise` 기반의 `fetch` 또는 `axios` 같은 라이브러리를 사용하는 것이 일반적
- 하지만 `XMLHttpRequest`는 여전히 구형 브라우저나 기존 코드베이스에서 유지보수를 위해 사용될 수 있음. 이를 이해하는 것은 과거와의 호환성을 위해 중요함.
---
- 참고 : 마이크로와 매크로 태스크
- 프로미스- javascript.info
https://whales.tistory.com/130
https://ko.javascript.info/promise-basics