- 자바스크립트 엔진은
- 싱글 스레드
- 이벤트 루프 개념을 기반
- 한 번에 한 개의 코드만 실행된다는 의미
- 작업 큐
- 실행 예정인 코드가 저장되는 곳
- 이벤트 루프
- 자바스크립트 엔진 내의 프로세스
- 코드 실행감시
- 작업 큐 관리
- 싱글 스레드
let button = document.getElementById("my-btn");
button.onclick = function(event) {
console.log("Clicked");
}
- 이벤트는 사용자 인터랙션에 대한 응답이나 그와 유사한 기능에 유용
- 더 복잡한 요구사항에는 유연하지 않다
- 호출할 함수가 인자로 전달되는 차이
- 콜백 패턴은 비동기 코드가 특정 시점까지 실행되지 않는다는 점에서 이벤트 모델과 유사
readFile("example.txt", function(err, contents) {
if (err)
throw err;
console.log(contents);
});
console.log("Hi!");
-
Node.js: error first callback style을 사용
- readFile()은 즉시 실행되기 시작하고 디스크로부터 파일을 읽기 시작할 때 멈춘다.
- console.log("Hi!");가 먼저 실행된다.
- readFile()은 즉시 실행되기 시작하고 디스크로부터 파일을 읽기 시작할 때 멈춘다.
-
readFile()이 실행 완료
- 작업 큐의 맨 뒤에
- 콜백 함수와
- 콜백 함수의 인자를 가진 새로운 작업이
- 추가
- 앞서 모든 작업 완료 후 실행
- 추가
- 작업 큐의 맨 뒤에
// 콜백 패턴은 여러 개의 호출 연결이 쉬워
// 이벤트보다 더 유연하다
readFile("example.txt", function(err, contents) {
if (err)
throw err;
writeFile("example.txt", function(err) {
if (err)
throw err;
console.log("File was written!");
});
});
- 길어지면 HELL!!!!!!!!!!!!!!!!!!
- 프로미스는 비동기 연산의 결과를 위한 플레이스 홀더
- 이벤트를 구독하거나 함수에 콜백을 전달하는 대신
- 프로미스를 반환할 수 있다.
// readFile이 앞으로 어떤 시점에 완료할 것을 약속함
let promise = readFile("example.txt");
- 이 코드에서 readFile()은 파일을 즉시 읽기 시작하지 않고
- 나중에 읽는다.
- 대신
- 함수는 비동기 읽기 연산을 나타내는 프로미스 객체를 반환
- 나중에 그 작업을 실행가능
- 언제 작업할 수 있는지는 전적으로 프로미스의 생명주기가 어떻게 종료되는지에 달려 있다.
- 나중에 그 작업을 실행가능
- 함수는 비동기 읽기 연산을 나타내는 프로미스 객체를 반환
- 대신
- 나중에 읽는다.
-
pending: 비동기 연산이 아직 완료되지 않았음을 가리키는 보류
- 그리고 짧은 생명주기를 통과
- 보류 프로미스는
- 미확정(unsettled) 상태로 간주된다.
- 보류 프로미스는
- 그리고 짧은 생명주기를 통과
-
위 예제의 프로미스는 readFile() 함수가
- 그 프로미스를 반환하는 시점에 보류 상태에 있게 됨다.
-
비동기 연산이 완료
- 이 프로미스는
- 확정(settled) 상태로 간주
- 두 가지 가능한 상태 중 하나가 된다.
- 확정(settled) 상태로 간주
- 이 프로미스는
-
성공(Fulfilled):
- 프로미스의 비동기 연산이 성공적으로 완료되었다.
-
실패(Rejected):
- 프로미스의 비동기 연산이 에러나 다른 이유 때문에 성공적으로 완료되지 않았다.
-
프로미스 내부의 [[PromiseState]] 프로퍼티는 프로미스의 상태를 반영하여
- pending
- fulfiled
- rejected
-
로 설정
- 이 프로퍼티는 프로미스 객체에 노출되지 않으므로 프로그래적으로 어떤 상태를 정할 수 없다.
-
BUT~~~~~~~~~~
- then() 메서드를 사용하여 프로미스의 상태가 변경될 때 특정 동작을 취하도록 할 수 있다.
-
then() 메서드는 모든 프로미스에 존재하며 두 개의 인자를 받는다.
- 첫 번째:
- 성공했을 때 호출하는 함수
- 추가적인 데이터는 성공함수
- 성공했을 때 호출하는 함수
- 두 번째:
- 프로미스가 실패했을 때 호출할 함수
- 추가적인 데이터는 실패함수
- 프로미스가 실패했을 때 호출할 함수
- 첫 번째:
let promise = readFile("example.txt");
promise.then(
function (contents) {
// 성공 시
console.log(contents);
},
function(err) {
// 실패 시
console.log(err.message);
});
promise.then(function(contents) {
// 성공 시
console.log(contents);
});
promise.then(null, function(err) {
// 실패 시
console.log(err.message);
});
promise.catch(function(err) {
// 실패 시
console.log(err.message);
});
세 가지 then()은 모두 같은 프로미스에서 호출되고 있다.
- 성공, 실패
- 성공
- , 실패..... then(null, function~~
- 실패만.... catch(function~~
만 처리 하는 중
-
장점
- 이벤트는 에러 존재 시 발생 x
- 콜백은 항상 에러 인자 검사를 수행해야만 한다
-
프로미스가 이미 확정 상태가 된 후 작업큐에 추가되었더라도 성공이나 실패 핸들러는 여전히 실행될 것이다.
- 이는 언제든지 새로운 성공핸들러나 실패 핸들러를 추가할 수 있으며 그에 대한 호출을 보장한다는 의미
let promise = readFile("example.txt");
// 원본 성공 핸들러
promise.then(function(contents) {
console.log(contents);
// 또 다른 성공 핸들러 추가
promise.then(function(contents) {
console.log(contents);
});
});
- 새로운 프로미스는
- new Promise()
- 이 때 생성자는 프로미스 초기화 코드를 포함하는
- 실행자(executor) 함수 하나를 인자로 받는다
- 실행자에는
- resolve()
- reject()
- 두 함수가 인자로 전달
- 실행자에는
- 실행자(executor) 함수 하나를 인자로 받는다
- 이 때 생성자는 프로미스 초기화 코드를 포함하는
- new Promise()
// Node.js 예제
let fs = require("fs");
function readFile(filename) {
return new Promise((resolve, reject) => {
// 비동기 연산 수행
fs.readFile(
filename,
{ encoding: "utf8"},
function(err, contents) {
// failed
if(err) {
reject(err);
return;
}
// succeeded
resolve(contents);
}
);
});
}
let promise = readFile("example.txt");
promise.then(
function(contents) {
// 성공 시
console.log(contents);
},
function(err) {
// 실패 시
console.err(err.message);
}
);
- resolve() 호출은
- 비동기 연산을 작동 시킨다.
- 프로미스를 생성하면
- 프로미스의 실행자가 실행을 완료 후
- 성공과 실패 핸들러가 항상 작업큐의 맨 뒤에 추가된다.. .lol
- 프로미스의 실행자가 실행을 완료 후
- Promise 생성자는 미확정 프로미스를 만들기 위한 최적의 방법이며,
- 이는 프로미스 실행자가 실행을 동적으로 하는 특징 때문이다.
- 그러나 프로미스가 한 가지 값만 표현하길 원한다면,
- 단순히 resolve() 함수에 값을 전달하는 작업을 스케줄링 하는 것은 의미가 없다.
- 그러나 프로미스가 한 가지 값만 표현하길 원한다면,
- 이는 프로미스 실행자가 실행을 동적으로 하는 특징 때문이다.
let promise = Promise.resolve(42);
promise.then(function(value) {
console.log(value); // 42
}); // 실패 핸들러 절대 호출x
promise = Promise.reject(42);
promise.catch(function(value) {
console.log(value); // 42
}); // 성공 핸들러 절대 호출x
- promise.resolve()나 Promise.reject() 메서드 중 하나에 프로미스를 전달하면,
- 그 프로미스는 변경없이 그대로 반환된다.
- Promise.resolve(), Promise.reject() 둘 다 인자로 프로미스가 아닌 대너블(thenable)도 받을 수 있다.
- 프로미스가 아닌 대너블이 전달되면 이 메서드는 then() 함수 이후에 호출되는 새로운 프로미스를 만든다.
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
}
- 이 예제에서 thenable 객체는 then() 메서드 외에 프로미스와 관련된 특징이 없다.
- thenable을 성공한 프로미스로 변경하기 위해 Promise.resolve()를 호출할 수 있다.
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
let p1 = Promise.resolve(thenable);
p1.then(function(value) {
console.log(value); // 42
});
-
Promise.resolve()는
- thenable.then()을 호출
- 프로미스 상태를 결정
- thenable.then()을 호출
-
이와 비슷하 방식으로 thenable에서 실패한 프로미스를 만들 수 있다.
-
why??????/
- es6 이전 라이브러리들은
- 프로미스 도입 전 부터
- thenable 사용
- 그래서 호환성을 갖기 위해 thenable 추가
- thenable 사용
- 프로미스 도입 전 부터
- es6 이전 라이브러리들은
-
그래서
- 객체가 프로미스인지 잘 모르면
- Promise.resolve(), Promise.reject()에 객체를 전달하는 것이 프로미스를 알아내는 좋은 방법
- 프로미스일 경우 변경없이 전달될 것이기 때문이다.
- Promise.resolve(), Promise.reject()에 객체를 전달하는 것이 프로미스를 알아내는 좋은 방법
- 객체가 프로미스인지 잘 모르면
- 만약 실행자에서 에러가 발생하면 프로미스의 실패 핸들러가 호출된다.
let promise = new promise(function(resolve, reject) {
throw new Error("Burst!!!!!");
});
promise.catch(function(error) {
console.log(error.message); // "Explosion!"
});
-
모든 실행자는 내부적으로 try-catch를 가지고 있으므로 에러를 잡고 에러 객체를 실패 핸들러에 전달
-
위 코드는 아래와 같은 코드
let promise = new promise(function(resolve, reject) {
try {
throw new Error("Burst!!!!!");
} catch (ex) {
reject(ex);
}
});
promise.catch(function(error) {
console.log(error.message); // "Explosion!"
});
- 프로미스에서
- 가장 논란이 되는 부분은???
- 실패 핸들러 없이 실패했을 때 발생하는 암묵적인 실패!!!
- 프로미스 특성 상
- 프로미스 실패가 처리되었는지 판단하는 것은 프로미스의 특성 때문에 간단하지 않다.
- 가장 논란이 되는 부분은???
let rejected = Promise.rejected(42);
// 이 시점에서는 실패 처리x
// 어느 정도 시간이 흐른 후...
rejected.catch(function(value) {
// 이제 실패가 처리됨
console.log(value);
});
- Node.js는 프로미스 실패 처리와 관련된
- process 객체에서 두 개의 이벤트를 발생 시킨다.
- unhandledRejection:
- 프로미스가 실패하고 같은 이벤트 루프 턴에서 실패 핸들러가 호출되지 않으면 발생
- 인자:
- 실패 이유 (에러 객체)
- 실패한 프로미스
- 인자:
- 프로미스가 실패하고 같은 이벤트 루프 턴에서 실패 핸들러가 호출되지 않으면 발생
- rejectionHandled:
- 프로미스가 실패하고 이벤트 루프의 턴 이후 실패 핸들러가 호출되면 발생
- 인자:
- 실패한 프로미스
- 인자:
- 프로미스가 실패하고 이벤트 루프의 턴 이후 실패 핸들러가 호출되면 발생
- unhandledRejection:
- process 객체에서 두 개의 이벤트를 발생 시킨다.
let rejected;
process.on("unhandledRejection", function(reason, promise) {
console.log(reason.message); // "Burst!"
console.log(rejected == promise); // true
});
rejected = Promise.reject(new Error("Burst!"));
let rejected;
process.on("rejectionHandled", function(promise) {
console.log(rejected === promise); // true
});
rejected = Promise.reject(new Error("Burst!"));
// 실패 핸들러 추가를 기다림
setTimeout(function(){
rejected.catch(function(value) {
console.log(value.message); // "Burst!"
});
}, 1000);
-
rejectionHandled 이벤트는 실패 핸들러가 최종적으로 호출되었을 때 발생한다.
- 만약 실패 핸들러가 rejected가 만들어진 후 rejected에 직접 연결 되었다면, 이 이벤트는 발생하지 않았을 것이다. ???
- 즉, 실패 핸들러가 rejected가 만들어진 이벤트 루프와 같은 턴에서 호출되는 경우, 유용하지 않다.
- 만약 실패 핸들러가 rejected가 만들어진 후 rejected에 직접 연결 되었다면, 이 이벤트는 발생하지 않았을 것이다. ???
-
처리되지 않을 가능성이 있는 실패를 적절히 추적하려면, rejectionHandled와 unhandledRejection 이벤트를 사용해 그 실패들의 리스트를 저장
- 그리고 나서 리스트를 검사하기 위해서 약간의 시간을 기다려야 한다.???
let possiblyUnhandledRejections = new Map();
// 실패가 처리되지 않았을 때, Map에 실패를 추가
process.on("unhandledRejection", function(reason, promise) {
possiblyUnhandledRejections.set(promise, reason);
});
process.on("rejectionHandled", function(promise) {
possiblyUnhandledRejections.delete(promise);
});
setInterval(function() {
possiblyUnhandledRejections.forEach(function(reason, promise) {
console.log(reason.message ? reason.message : reason);
//이 실패를 처리하기 위한 작업 수행
handleRejection(promise, reason);
});
possiblyUnhandledRejections.clear();
}, 60000);
- Map
- key: promise
- value: 프로미스의 이유
- 과정
- unhandledRejection 이벤트가 발생할 때마다 프로미스와 실패 이유는 Map에 추가된다.
- rejectionHandled 이벤트가 발생할 때마다 Map에서 처리된 프로미스가 제거된다.
- possiblyUnhandledRejections는 이벤트가 호출될 때마다 늘어나고 줄어든다.
- setInterval() 호출은 처리되지 않을 가능성이 있는 실패 리스트를 주기적으로 검사하고 콘솔에 정보를 출력한다.
- 실제로는 로그를 남기거나 다른 방법으로 처리
- 위 예제에서는 어떤 프로미스가 존재하는지 살펴보기 위해 정기적으로 검사할 필요가 있기 때문에
- Weak Map 대신 Map 사용?????????????????????????????
- 브라우저도 마찬가지로 처리되지 않은 실패를 식별하도록 돕는 두 개의 이벤트를 발생시킨다.
- 이 이벤트들은 window 객체에서 발생하며 Node.js와 실질적으로 동일하다.
- 종류
- unhandledrejection: 프로미스가 실패하고 같은 이벤트 루프 턴에서 실패 핸들러가 호출되지 않으면 발생
- rejectionhandled: 프로미스가 실패하고 이벤트 루프의 턴 이후 실패 핸들러가 호출되면 발생
! Node.js 구현에서 이벤트 핸들러는 개별적인 매개변수를 전달받지만, 브라우저의 이벤트 핸들러는 다음 프로퍼티를 가진 이벤트 객체를 받는다.
- 이벤트 객체
- type: 이벤트의 이름("unhandledrejection"이나 "rejectionhandled")
- promise: 실패한 프로미스 객체
- reason: 프로미스로부터 받은 실패 이유
- 브라우저 구현의 차이점은 실패 이유(reason)를 두 이벤트에서 모두 이용할 수 있다는 것이다.
let rejected;
window.onunhandledrejection = function(event) {
console.log(event.type); // "unhandledrejection"
console.log(event.reason.message); // "Burst!"
console.log(rejected === event.promise) // true
};
window.onrejectionhandled = function(event) {
console.log(event.type); // "rejectionhandled"
console.log(event.reason.message); // "Burst!"
console.log(rejected === event.promise); // true
};
rejected = Promise.reject(new Error("Burst!"));
-
위 처럼 DOM Level 0 표기법인 onunhandledrejection과 onrejectionhandled를 사용하여 두 이벤트 핸들러를 할당
-
or
-
addEventListener("unhandledrejection")과 addEventListener("rejectionhandled") 사용 가능
-
각 이벤트 핸들러는 실패한 프로미스에 대한 정보를 가진 이벤트 객체를 받는다.
- type
- promise
- reason
-
브라우저에서 처리되지 않은 실패를 추적하는 코드는 Node.js와 매우 유사
let possiblyUnhnadledrejections = new Map();
// 실패가 처리되지 않았을 때, Map에 실패를 추가
window.onunhandledrejection = function(event) {
possiblyUnhandledRejections.set(event.promise, event.reason);
};
window.onrejectionhandled = function(event) {
possiblyUnhandledRejections.delete(event.promise);
};
setInterval(function() {
possiblyUnhandeldRejections.forEach(function(reason, promise) {
console.log(reason.message ? reason.message : reason);
// 위 실패를 처리하기 위한 작업 수행
handleRejection(promise, reason);
});
possiblyUnhandledRejections.clear();
}, 60000);
- 이벤트 핸들러에서 정보를 저장받는 위치
- 프로미스
- 콜백과 setTimeout() 함수의 조합을 약간 개선??
- 보기보다 더 많은 장점이 있다.
- 콜백과 setTimeout() 함수의 조합을 약간 개선??
- 특히, 복잡한 비동기 동작을 수행하기 위해 프로미스를 연결하는 여러 가지 방법이 존재한다.
- then()
- catch()
- 또 다른 프로미스를 만들어 반환한다.
- 이 두번째 프로미스는 첫 번째 프로미스가 성공하거나 실패했을 때만 처리된다.
let p1 = new Promise(function(resolve, reject) {
resolve(42);
});
p1
.then(function(value) {
console.log(value);
}).then(function() {
console.log("finished!");
});
42
finished
###11.4.1 에러 처리
let p1 = new Promise(function(resolve, reject) {
resolve(42);
});
p1.then(function(value) {
throw new Error("Boom!");
}).catch(function(error) {
console.log(error.message); // "Boom!"
});
p1.then(function(value) {
throw new Error("Boom!");
}).then(null, function(error) {
console.log(error.message); // "Boom!"
});
p1.then(function(value) {
throw new Error("Boom!");
}).then((value) => {
console.log(value);
}, function(error) {
console.log(error.message); // "Boom!"
}).then(function(value) {
console.log("last");
});
p1.then(function(value) {
throw new Error("Boom!");
}).catch(function(err) {
console.log("first error: " + err);
return 42;
// return new Promise(resolve, reject) {
// console.log("inside first error:!");
// resolve(0);
// };
}).then((value) => {
console.log(value + " after error!");
}, function(error) {
console.log(error.message); // "Boom!"
}).then(function(value) {
console.log("last");
}).catch(function(err) {
console.log("last error: " + err);
});
- 프로미스 연결 마지막에 실패 핸들러를 추가하면 어떤 발생가능한 에러든 적절하게 처리되는 것을 항상 보장
- 다음 프로미스에 데이터를 전달하는 기능
// 성공 핸들러
let p1 = new Promise(function(resolve, reject) {
resolve(42);
});
p1.then(function(value) {
console.log(value); // 42
return value + 1;
}).then(function(value) {
console.log(value) // 43
});
// 실패 핸들러
p1 = new Promise(function(resolve, reject) {
reject(42);
});
p1.catch(function(value) {
console.log(value); // 42
return value + 1;
}).then(function(value) {
console.log(value) // 43
});
let p1 = new Promise(function(resolve, reject) {
resolve(42);
});
let p2 = new Promise(function(resolve, reject) {
resolve(43);
});
p1.then(function(value) {
// 첫 번째 성공 핸들러
console.log(value); // 42
return p2;
}).then(function(value) {
// 두 번째 성공 핸들러
console.log(value); // 43
});
let p1 = new Promise(function(resolve, reject) {
resolve(42);
});
let p2 = new Promise(function(resolve, reject) {
resolve(43);
});
let p3 = p1.then(function(value) {
// 첫 번째 성공 핸들러
console.log(); // 42
return p2;
});
p3.then(function(value) {
// 두 번째 성공 핸들러
console.log(value);
});
- *** 두 번째 성공 핸들러가 p2가 아닌 p3 즉 세번째 프로미스에 추가**
let p1 = new Promise(function(resolve, reject) {
resolve(42);
});
let p2 = new Promise(function(resolve, reject) {
reject(43);
});
p1.then(function(value) {
// 첫 번째 성공 핸들러
console.log(value); // 42
return p2;
}).then(function(value) {
// 두 번째 성공 핸들러
console.log(value); // 호출되지 않음
});
// 에러 잡으면 나옴
p1.then(function(value) {
// 첫 번째 성공 핸들러
console.log(value); // 42
return p2;
}).catch(function(value) {
// 두 번째 성공 핸들러
console.log(value); // 호출되지 않음
});
-
프로미스가 성공하던 실패하던 thenable 반환~
let thenable = { then: function(resolve, reject) { resolve(42); } };
-
thenable을 반환한다는 것은 프로미스 결과에 대한 추가 응답을 정의할 수 있다는 의미이다.
let p1 = new Promise(function(resolve, reject) {
resolve(42);
});
p1.then(function(value) {
console.log(value); // 42
// 새로운 프로미스를 만듬
let p2 = new Promise(function(resolve, reject) {
resolve(43);
});
return p2;
}).then(function(value) {
console.log(value); // 43
});
- 이 패턴은 또 다른 프로미스를 실행시키기 전에 이전의 프로미스가 확정될 때까지 기다리길 원할 때 유용하다.
- Promise.all()
- Promise.race()
- Promise.all()
- 관리할 프로미스들의 이터러블(배열 같은) 인자 하나를 받고, 이터러블 내 모든 프로미스가 처리된 경우에만 처리된 프로미스 하나를 반환
- 반환된 프로미스는 다음 예제처럼 이터러블 내의 모든 프로미스가 성공했을 때 성공
- 관리할 프로미스들의 이터러블(배열 같은) 인자 하나를 받고, 이터러블 내 모든 프로미스가 처리된 경우에만 처리된 프로미스 하나를 반환
let p1 = new Promise(function(resolve, reject) {
resolve(42);
});
let p2 = new Promise(function(resolve, reject) {
resolve(42);
});
let p3 = new Promise(function(resolve, reject) {
resolve(44);
});
let p4 = Promise.all([p1, p2, p3]);
p4.then(function(value) {
console.log(Array.isArray(value)); // true
console.log(value[0]); // 42
console.log(value[1]); // 43
console.log(value[2]); // 44
});
- 하나라도 실패 시!
let p1 = new Promise(function(resolve, reject) {
resolve(42);
});
let p2 = new Promise(function(resolve, reject) {
reject(42);
});
let p3 = new Promise(function(resolve, reject) {
resolve(44);
});
let p4 = Promise.all([p1, p2, p3]);
p4.catch(function(value) {
console.log(Array.isArray(value)); // false
console.log(value); // 43
});
- 실패 핸들러는 배열이 아닌
- 하나의 값만을 받는다.
- 딱! 실패한 그 프로미스의 결과 값!
- 하나의 값만을 받는다.
- 여러 개의 프로미스를 관찰
- 하지만 약간 다른 방식
- 프로미스ㅡ의 이터러블을 받고 프로미스 하나 반환
- 반환된 프로미스는 첫 번째 프로미스가 확정되자마자 확정
- Promise.all() 처럼 모든 프로미스가 성공되길 기다리는 대신!!!!!!!!!!
- Promise.race()는 배열의 어떤 프로미스라도 성공하면 바로 그에 맞는 프로미스를 반환
- 반환된 프로미스는 첫 번째 프로미스가 확정되자마자 확정
- 프로미스ㅡ의 이터러블을 받고 프로미스 하나 반환
- 하지만 약간 다른 방식
let p1 = Promise.resolve(42);
let p2 = new Promise(function(resolve, reject) {
resolve(43);
});
let p3 = new Promise(function(resolve, reject) {
resolve(44);
});
let p4 = Promise.race([p1, p2, p3]);
p4.then(function(value) {
console.log(value); // 42
});
- 실패 시
let p1 = Promise.resolve(42);
let p2 = new Promise(function(resolve, reject) {
reject(43);
});
let p3 = new Promise(function(resolve, reject) {
resolve(44);
});
let p4 = Promise.race([p1, p2, p3]);
p4.catch(function(value) {
console.log(value); // 43
});
- Promise.race()가 호출되었을 때 p2가 이미 실패 상태이기 때문에 p4 또한 실패한다.
- p1과 p3가 성공하더라도 이는 p2가 실패한 후 발생하는 일이므로 무시된다.
- 다른 내장 타입처럼 파생 클래스의 기반 클래스로 프로미스를 사용할 수 있다.
- 이는 내장 프로미스의 기능을 확장하기 위하여 프로미스의 변형을 정의할 수 있다.
- then(), catch() 말고
- success, failure를 사용하고 싶을 때
- then(), catch() 말고
- 이는 내장 프로미스의 기능을 확장하기 위하여 프로미스의 변형을 정의할 수 있다.
class MyPromise extends Promise {
// 기본 생성자 사용
success(resolve, reject) {
return this.then(resolve, reject);
}
failure(reject) {
return this.catch(reject);
}
}
let promise = new MyPromise(function(resolve, reject) {
resolve(42);
});
promise.success(function(value) {
console.log(value);
}).failure(function(value) {
console.log(value);
});