[230526] JS 비동기 프로그래밍
1. 비동기 프로그래밍 학습
오늘은 비동기 프로그래밍 callback 방식과 promise 방식에 대해 학습했다.
- JavaScript 는 단일 스레드에서 동작=> 한번에 한가지 일만 할 수 있음
- 싱글스레드만으로 멀티스레드 부럽지 않은 부드러운 소프트웨어를 만들기 위해서는 대가를 치뤄야 한다. 그 대가가 바로 비동기적(asynchronous) 프로그래밍
콜백 방식
- 자바 스크립트에서 함수는 일급 객체이므로 파라미터로 넘길 수 있음
// 콜백함수 예시
function loadScript(src, callback) {
let script = document.createElement("script");
script.src = src;
script.onload = () => callback(script);
document.head.append(script);
}
- 콜백지옥, 멸망의 피라미드 -> 프라미스로 해결
//멸망의 피라미드 예시
loadScript("1.js", function (error, script) {
if (error) {
handleError(error);
} else {
// ...
loadScript("2.js", function (error, script) {
if (error) {
handleError(error);
} else {
// ...
loadScript("3.js", function (error, script) {
if (error) {
handleError(error);
} else {
// 모든 스크립트가 로딩된 후, 실행 흐름이 이어집니다. (*)
}
});
}
});
}
});
- [학습 자료 및 코드 출처] 모노 자바스크립트
-
[[추가 강의 자료] 자바스크립트 11. 비동기 처리의 시작 콜백 이해하기, 콜백 지옥 체험 😱 JavaScript Callback 프론트엔드 개발자 입문편 (JavaScript ES6)](https://www.youtube.com/watch?v=s1vpVCrT8f4)
promise 방식
- Promise는 제작코드, 소비코드를 연결해주는 객체이다.
let promise = new Promise(function (resolve, reject) {
// executor (제작 코드, '가수')
});
let promise = new Promise(function (resolve, reject) {
resolve("완료");
reject(new Error("…")); // 무시됨
setTimeout(() => resolve("…")); // 무시됨
});
- resolve, reject는 js에서 자체 제공하는 콜백
- resolve(value) - 일이 성공적으로 끝난 경우
- reject(error) - 에러와 함께 호출
- 콜백을 동작에 따라 내부 프로퍼티가 변경 됨 (state,result)
- state와 result는 .then/.catch/.finally 메서드를 사용하면 접근 가능 (직접 접근 x)
.then
- 프라미스에서 기본적인 메서드
- 여러 개 가능
- 첫번째 인수에는 프라미스가 이행되었을때, 두번째 인수는 거부되었을때 실행
promise.then(
(result) => alert(result), // 1초 후 "완료!"를 출력
(error) => alert(error) // 실행되지 않음
);
catch
- 에러가 발생한 경우만 다루고 싶을때
- .then(null,f) 와 동일함
let promise = new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("에러 발생!")), 1000);
});
// .catch(f)는 promise.then(null, f)과 동일하게 작동합니다
promise.catch(alert); // 1초 뒤 "Error: 에러 발생!" 출력
.finally
- try catch 의 finally 절처럼 결과가 어떻든 실행
- .then(f,f)와 같진않음
- finally 핸들러엔 인수 없음
- 자동으로 에러와 결과를 전달함
- 문법적 측면에서도 편리
new Promise((resolve, reject) => {
/* 시간이 걸리는 어떤 일을 수행하고, 그 후 resolve, reject를 호출함 */
})
// 성공·실패 여부와 상관없이 프라미스가 처리되면 실행됨
.finally(() => 로딩 인디케이터 중지)
.then(result => result와 err 보여줌 => error 보여줌)
간략하게 적을랬는데 생각보다 길어졌다. 추후에는 async, await 학습하기
Leave a comment