코드 실행의 종료를 기다리는 제어권이 있음
코드 실행의 종료를 관여하지 않음
block vs non-block
비동기 작업을 동기처럼 체이닝할 수 있게 해주는 객체
const myFirstPromise = new Promise((resolve, reject) => {
// do something asynchronous which eventually calls either:
//
// resolve(someValue) // fulfilled
// or
// reject("failure reason") // rejected
});
여러 promise를 받아서 처리하는 함수
Promise.all([
new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1
new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
new Promise(resolve => setTimeout(() => resolve(3), 1000)) // 3
]).then(alert); // 프라미스 전체가 처리되면 1, 2, 3이 반환됩니다. 각 프라미스는 배열을 구성하는 요소가 됩니다.
여러 개의 promise를 체이닝해주는 함수
p.then(onFulfilled, onRejected);
p.then(function(value) {
// 이행
}, function(reason) {
// 거부
});
에러를 처리해주는 함수
p1.then((value) => {
console.log(value); // "Success!"
return Promise.reject("oh, no!");
})
.catch((e) => {
console.error(e); // "oh, no!"
})
.then(
() => console.log("after a catch the chain is restored"), // "after a catch the chain is restored"
() => console.log("Not fired due to the catch"),
);
promise 패턴을 이용해 네트워크 요청 비동기 처리를 동기적으로 구현할 수 있도록 해주는 함수
fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'})
.then(function(response) {
return response.text();
})
.then(function(text) {
console.log('Request successful', text);
})
.catch(function(error) {
log('Request failed', error)
});
const PROMISE_STATES = {
PENDING: "PENDING",
FULFILLED: "FULFILLED",
REJECTED: "REJECTED",
};
class MyPromise {
state = PROMISE_STATES.PENDING;
resolveCallback = null;
rejectCallback = null;
constructor(executor) {
this.state = PROMISE_STATES.PENDING;
try {
executor(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
this.reject(error);
}
}
resolve(value) {
if (this.state !== PROMISE_STATES.PENDING) return; // Prevent duplicate calls
this.state = PROMISE_STATES.FULFILLED;
this.value = value;
if (this.resolveCallback) {
this.resolveCallback(value); // Execute registered callback
}
}
reject(error) {
if (this.state !== PROMISE_STATES.PENDING) return; // Prevent duplicate calls
this.state = PROMISE_STATES.REJECTED;
this.value = error;
if (this.rejectCallback) {
this.rejectCallback(error); // Execute registered callback
}
}
then(resolve, reject) {
return new MyPromise((rs, rj) => {
if (this.state === PROMISE_STATES.FULFILLED) {
try {
const result = resolve ? resolve(this.value) : this.value;
rs(result);
} catch (error) {
rj(error);
}
} else if (this.state === PROMISE_STATES.REJECTED) {
try {
const result = reject ? reject(this.value) : this.value;
rs(result);
} catch (error) {
rj(error);
}
} else {
// Save callbacks if the state is PENDING
this.resolveCallback = () => {
try {
const result = resolve(this.value);
rs(result);
} catch (error) {
rj(error);
}
};
this.rejectCallback = () => {
try {
const result = reject(this.value);
rj(result);
} catch (error) {
rj(error);
}
};
}
});
}
catch(callback) {
return this.then(null, callback);
}
}
const promise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve("Step 1"); // 첫 번째 단계에서 성공
// reject("Error at Step 1"); // 이걸로 테스트하려면 주석 해제
}, 1000);
});
promise
.then((value) => {
console.log("First then:", value); // Step 1 출력
return "Step 2";
})
.then((value) => {
console.log("Second then:", value); // Step 2 출력
throw new Error("Error at Step 2"); // 오류 발생
})
.then((value) => {
console.log("Third then:", value); // 이 코드는 실행되지 않음
return "Step 3";
})
.catch((error) => {
console.error("Caught an error:", error.message); // Error at Step 2 출력
});
promise (PENDING) ── resolve("Step 1") ──> FULFILLED
│
▼
promise2 (PENDING) ── resolve("Step 2") ──> FULFILLED
│
▼
promise3 (PENDING) ── throw Error ──> REJECTED
│
▼
promise4 (catch) 실행