Promise
자바스크립트 비동기
재우
콜백의 안좋은점 발견
장희
이것을 해결하려면?
재민
Promise 사용방법
희환
프로미스의 사실과 오해
프라미스는 자바스크립트만의 전유물이다?
프라미스는 callback hell을 줄이기 위한 도구이다?
프라미스는 새로운 패턴이다?
새로운 패턴이다?
Promise 패턴은 1977년 병렬 처리를 위해 처음 고안된 패턴
이미 유료언어인 Java와
무료 언어들인 Scala, Python 등 많은 언어에 이미 존재
Javascript의 Promise는 병렬 쓰레드라는 점만 빼면
패턴이 가지고 있는 목적은 같다.

스펙으로 정의된 내용이 ES6 사양으로 책정되어 브라우저에 구현 된 것
프로미스는 자바스크립트만의 전유물?
Promise Implementations
| Implementation | DescriptionSpec | Version |
|---|---|---|
| jQuery (3.0 or newer) | jQuery is a fast, small, and feature-rich JavaScript library dealing with HTML document traversal, manipulation, event handling, animation, and Ajax. | 1.1 |
| ... | ... | .. |
Inside Frameworks
In Other Languages
| Language | Implementation | Description |
|---|---|---|
| Java | IOU | Promises/A+ for Java and Android |
| Python | promise | A clean and generic implementation of the Promises/A+ specification in Python |
| Swift | Then | A clean and generic implementation of the Promises/A+ specification in Python |
| PHP | Promise PHP Library | This is a Promises/A+ implementation in PHP. This handles promise chaining immutably until all context handler is all gone from execution context. |
Standalone
| Implementation | Description | Spec Version |
|---|---|---|
| es3-promise | An implementation of Promise then with ES3 syntax | 1.1 |
| Lie | Small library following the ES6 syntax | 1.1 |
callback hell을
줄이기 위한 도구이다?
var findFriends = function(username, callback){
db.connection(function(error){
if(!!error){
db.findUser(username, function(userdata){
if(!!userdata) {
db.findFriends(userdata.index, function(friends) {
if(friends.length > 0) {
callback(friends);
}
callback(userdata);
});
}
callback(username);
});
}
callback(error);
});
}var findFriends = promise.bind(function(username){
return promise.bind(db.connection)
}).then(function(error)){
if(!!error) {
throw new Error('데이터베이스 커넥션 에러');
}
return promise.bind(db.findUser, username);
}).then(function(userdata){
if(!!userdata) {
throw new Error('유저정보가 없습니다.');
}
return promise.bind(db.findFriends, userdata.index);
}).then(function(friends){
if(friends.length > 0) {
throw new Error('친구가 없습니다.')
}
return friends;
})프로미스의 목적과 본질
프로미스는 순차성과 믿음성이 결여되는 자바스크립트의 콜백을 믿을만한 중계자 역할을 하는 유틸리티를 통해 조화롭게 작동 할 수 있도록 유도한 완벽하진 않은 좀더 나은 방법이다.
책이 문젠지 번역이 문젠지 모르겠습니다.
Two such patterns are codified directly into the native ES6 Promise implementation, so we get them for free, to use as building blocks for other patterns.
그중 두 패턴은 ES6 Promise에 바로 구현되어 있으므로 무료이고 다른 패턴 조합에 필요한 블록으로 쓸 수 있다.(p.269)
프로미스는 비동기적 처리의 최종결과를 편리하게 전달하기 위해
존재하는 데이터 전송 추상화 컨테이너
프로미스는?
왜 프로미스라고 이름을
지었을까요?
아이가 설탕을 너무 좋아합니다.
건강에 나쁘다고 아무리 타일러도 말을 듣지 않아요.
그런데 선생님 말씀을 곧 잘 들으니
아이에게 설탕을 끊어 달라 한마디만 해주십시오
부탁을 들어드리겠습니다.
하지만 보름 뒤에 다시 오십시오.
먼 길을 왔습니다.
그냥 돌려보내지 마세요.
보름 뒤에 다시 오면 해드리겠습니다.
약속합니다.
보름 후...
얘야. 설탕을 많이 먹으면 건강을 해치니
먹지 않는 것이 좋겠구나
처음 선생님을 찾아 뵈었을때
어찌 보름 후에 다시 오라 하셨는지요?
실은 저도 설탕을 좋아해서
자주 먹고 있었습니다.
아이에게 설탕을 먹지 말라 하기 전
제가 먼저 설탕을 끊어야 했습니다.
간디의 이야기

요청 - 약속 - 보름뒤 실현 - 응답
프로미스라는 이름은..
프로미스는 미래의 어떤 시점이 되면 데이터를 채워주는 그릇
지금은 어려우나 나중에 반드시 최종 결과를 돌려주기로
약속(Promise)한다.
하지만 MIT의 컴퓨터 과학 명예교수인 칼 휴이트는 프로미스는 미래의 시점을 의미하지 않기 때문에 Future가 더 적합한 이름이라고 말했다....
자바는 Future.. 유료언어가 좋네요.
지금까지 3쪽 설명했습니다.
아니 정확히는 2쪽 1/2 했습니다.
지금값 나중값
function add(getX,getY,cb) {
var x, y;
getX(function(xVal){
x = xVal;
if (y != undefined) {
cb( x + y );
}
});
getY(function(yVal){
y = yVal;
if (x != undefined) {
cb( x + y );
}
});
}
add( fetchX, fetchY, function(sum){
console.log( sum );
});function add(xPromise, yPromise) {
return (
Promise.all([xPromise, yPromise])
.then(function(values) {
return values[0] + values[1]
})
)
}
add(fetchX(), fetchY())
.then(function(sum) {
console.log(sum)
})
약속은 간디가 약속한 것 처럼 이룸(fullfill)
영원한 사랑을 약속한 것처럼(rejection)
프로미스는
첫번째 인자로 이룸함수
두번째 인자로 버림함수
add(fetchX(), fetchY())
.then(
function(sum) {
console.log(sum);
},
function(err) {
console.error(err);
}
);프로미스 컨테이너인지
아닌지는 어떻게 확인할까?
프로미스의 값은 외부라이브러리나 프레임워크에서 전달받을 가능성이 있다.
Promise / A+ 명세에 따르면 then이라는 메서드를 가진 thenable 한 객체 또는 함수를 정의하여 판별 하는 것으로 규정
이러한 규정은 then이라는 메서드명을 가진
라이브러리와 혼란을 주기도 합니다.
if (
p !== null &&
(
typeof p === "object" ||
typeof p === "function"
) &&
typeof p.then === "function"
) {
// assume it's a thenable!
} else {
// not a thenable
}프로미스는 믿음!
콜백을 특정한 시점에 특정한 횟수로 받는다면..
1. 일찍 왔네
2. 늦게 왔네
3. 안왔네
3. 많이 왔네
4. 적게 왔네
5. 인자를 제대로 안넣었더니 제대로 안왔네
6. 에러나서 왔네
1. 일찍 왔네
then 을 건넨 콜백은 항상 비동기적으로 작동
2. 늦게 왔네
스케줄링 된 콜백은 비동기 시점에 예상대로 실행
3. 안왔네
race를 이용한 추상화를 이용하면 된다.
3. 많이 왔네
프로미스는 딱 한번 최초의 결과만 귀결(결과)을 취한다.
4. 적게 왔네
프로미스는 딱 한번 최초의 결과만 취하므로 안온것과 같다.
5. 인자를 제대로 안넣었더니 안왔네
2번째 값 부터는 무시 값을 여러개 넘기려면 배열이나 객체로 감싸야 한다.
6. 에러나서 왔네
프로미스가 생성 중 언제라도 에러가 나면 예외를 잡아 주어 프로미스를 버린다.
안왔네, 적게왔네
Race(경합)이라는 상위 수준의 추상화를 이용해 문제를 해결
// 프로미스를 타임아웃 시키는 유틸
function timeoutPromise(delay) {
return new Promise( function(resolve,reject){
setTimeout( function(){
reject( "Timeout!" );
}, delay );
} );
}
// 타임아웃 세팅
Promise.race( [
foo(),
timeoutPromise( 3000 )
] )
.then(
function(){
// 제 시간에 이루어짐
},
function(err){
// 제 시간에 이루어지지 않거나 foo()가 reject 됨
}
);에러나서 왔네
var p = new Promise( function(resolve,reject){
foo.bar(); // foo가 정의되지 않아서 에러
resolve( 42 ); // 뒤쪽 내용은 실행되지 않는다
} );
p.then(
function fulfilled(){
// 실행되지 않습니다
},
function rejected(err){
// 아마 에러는 타입에러
}
);var p = new Promise( function(resolve,reject){
resolve( 42 );
} );
p.then(
function fulfilled(msg){
foo.bar();
console.log( msg ); // 실행되지 않는다
},
function rejected(err){
// 여기서도 실행되지 않는다.
}
);Promise.resolve() 함수
var p1 = new Promise( function(resolve,reject){
resolve( 42 );
} );
var p2 = Promise.resolve( 42 );var p1 = Promise.resolve( 42 );
var p2 = Promise.resolve( p1 );
p1 === p2; // true프로미스 / thenable 아닌 값을 넣으면 프로미스를 손에 넣게됨
프로미스가 넘어가도 결과는 마찬가지
var p = {
then: function(cb) {
cb( 42 );
}
};
// 운이 좋아서 작동함
p
.then(
function fulfilled(val){
console.log( val ); // 42
},
function rejected(err){
// never gets here
}
);var p = {
then: function(cb,errcb) {
cb( 42 );
errcb( "evil laugh" );
}
};
p
.then(
function fulfilled(val){
console.log( val ); // 42
},
function rejected(err){
// 실행되면 안되는데 실행이 된다.
console.log( err ); // evil laugh
}
);Promise.resolve( p )
.then(
function fulfilled(val){
console.log( val ); // 42
},
function rejected(err){
// 실행되지 않는다.
}
);Promise.resolve()는 thenable인자를 받아 thenable이
아닌 값이 발견될 때까지 풀어봐서 진짜 프로미스를 내놓음.
용어정리: resolve, fullfill, reject

끝
Promise 발표
By leejaemin
Promise 발표
- 175