Contenu connexe Similaire à JavaScript Promises Similaire à JavaScript Promises (14) JavaScript Promises2. 01 02 03 04
Promise란
무엇인가?
Promise
사용하기
Promise의
특징
Promise 직접
구현하기
전통적인 콜백 패
턴이 가지고 있는
문제와 Promise 정
의및 사용 방법에
대해서 개괄적으로
살펴본다.
Promise의 정적 메
서드와 인스턴스
메 서 드 , 그 리 고
thenable에 관한
개념 등 조금 더 다
양하고 자세한 내
용을 살펴본다.
Promise에 대해
잘 알려져 있지 않
는 중요한 특징 몇
가지를 소개한다.
ES6
23. 전통적인 콜백 패턴의 문제 1
여러운 비동기 예외 처리
3
try{
setTimeout(function(){
throw new Error('에러가 발생했다.');
}, 1000);
}catch(err){
console.error(err);
console.log('에러를 복구했다.');
}
24. 전통적인 콜백 패턴의 문제 1
여러운 비동기 예외 처리
try{
setTimeout(function(){
throw new Error('에러가 발생했다.');
}, 1000);
}catch(err){
console.error(err);
console.log('에러를 복구했다.');
}
global
4
25. 전통적인 콜백 패턴의 문제 1
여러운 비동기 예외 처리
try{
setTimeout(function(){
throw new Error('에러가 발생했다.');
}, 1000);
}catch(err){
console.error(err);
console.log('에러를 복구했다.');
}
global setTimeout() handler
호출
콜백 등록
5
26. 전통적인 콜백 패턴의 문제 1
여러운 비동기 예외 처리
try{
setTimeout(function(){
throw new Error('에러가 발생했다.');
}, 1000);
}catch(err){
console.error(err);
console.log('에러를 복구했다.');
}
global time eventsetTimeout() handler
호출
콜백 등록
발화
6
27. 전통적인 콜백 패턴의 문제 1
여러운 비동기 예외 처리
try{
setTimeout(function(){
throw new Error('에러가 발생했다.');
}, 1000);
}catch(err){
console.error(err);
console.log('에러를 복구했다.');
}
global time eventsetTimeout() handler
호출
콜백 등록
발화
예외
7
28. 전통적인 콜백 패턴의 문제 1
여러운 비동기 예외 처리
try{
setTimeout(function(){
throw new Error('에러가 발생했다.');
}, 1000);
}catch(err){
console.error(err);
console.log('에러를 복구했다.');
}
global time eventsetTimeout() handler
호출
콜백 등록
발화
예외 통지예외
8
29. 전통적인 콜백 패턴의 문제 2
복수의 비동기 처리
fs.readdir(source, function(err, files){
if(err){
console.log('Error finding files : ' + err);
}else{
file.forEach(function(filename, fileIndex){
console.log(filename);
gm(source + filename).size(function(err, vlaues){
if(err){
console.log('Error identifying file size : ' + err);
}else{
console.log(filename + ' : ' + values);
aspect = (values.width / value.height);
widths.forEach(function(width, wwidthIndex){
height = Math.round(width /aspect);
console.log('resizing ' + filename + 'to ' + height + 'x' + height);
this.resize(width, height).write(
destination + 'w' + width + '_' + filename,
function(err){
if(err){
console.log('Error writing file : ' + err);
}
}
);
});
}
});
});
}
})
9
34. Promise란?
효과
전통적인 콜백 패턴이 가진 단점을 일부 보완한다.
비동기 처리 시점을 명확하게 표현한다.
Promise 객체의 인터페이스를 이용해 다양한 비동기 처리를 패턴화할 수 있다.
복잡하고 불편한 비동기 예외 처리를 손쉽게 다룰 수 있다.
11
39. Promise란?
사용된 곳
if('serviceWorker' in navigator){
navigator.serviceWorker.register('/sw=text/sw.js', {
scope: '/'
}).then(function(sw){
// registration worked
console.log('Registration succeeded.');
}).catch(function(err){
// registration filed
console.log('Registration filed with ' + err);
})
}
function writeArrayToStream(array, writableStream){
array.forEach(chunk = writableStream.write(chunk));
return writableStream.close();
}
writeArrayToStream([1, 2, 3, 4, 5], writableStream)
.then(() = console.log('All done!'))
.catch(e = console.log('Error with the stream : ' + e));
Service Worker API
Streams API
13
43.
Constructor
var promise = new Promise(function(resolve, reject){
// 비동기 처리 작성
// 처리가 끝나면 resolve 또는 reject 호출
});
Instace Method Static Method
Promise.prototype.then(onFulfilled,
51. Promise 살펴보기
워크플로우
/**
* @returns {Promise}
*/
function asyncFunction(){
return new Promise(function(resolve, reject){
setTimeout(function(){
resolve('Async Hello world!!');
}, 16);
})
}
asyncFunction().then(function(value){
console.log(value);
}).catch(function(error){
console.log(error);
});
asyncFunction().then(function(value){
console.log(value);
}, function(error){
console.log(error);
});
asyncFunction()은 Promise의 인스턴스를
반환할 뿐이며 비동기 로직은 모두
Promise에 추상화된다.
비동기 처리가 성공했을 때 호출될 콜백은
then(), 실패했을 때 호출될 콜백은
catch()로 등록한다.
catch()는 then()을 이용해 대체할 수도
있다.
15
83. Promise 맛보기
객체 생성
1. new Promise(fn)으로 promise 객체를 생성한다.
2. fn에는 비동기 처리를 작성한다.
• 처리 결과가 정상이라면 resolve(결과 값)을 호출한다.
• 처리 결과가 비정상이라면 reject(error)을 호출한다.
function getJSON(URL){
return new Promise(function(resolve, reject){
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function(){
if(req.status === 200){
resolve(JSON.parse(req.responseText));
}else{
reject(new Error(req.statusText));
}
};
req.onerror = function(){
reject(new Error(req.statusText));
};
req.send();
})
}
function doSomething(callback){
var value = 42;
if(value === 42){
callback(null, value);
}else{
callback(new Error('에러'), null);
}
}
17
209.
var promise = new Promise(function(resolve){
resolve(42);
}).then(function(value){
console.log(value);
});
var promise = Promise.resolve(42).then(function(value){
console.log(value);
});
24
257.
26
var promise = Promise.resolve($.ajax('/api/comments'));
promise.then(function(value){
console.log(value);
}).catch(function(error){
console.log(error.statusText);
});
노트
312.
27
var promise = new Promise(function(resolve, reject){
reject(new Error('오류'));
}).catch(function(error){
console.log(error.message);
});
Promise.reject(new Error('오류')).catch(function(error){
console.log(error.message);
});
348.
29
function taskA(){
console.log('Task A');
}
function taskB(){
console.log('Task B');
}
function onRejected(error){
console.log('Catch Error: A or B', error);
}
function finalTask(){
console.log('Final Task');
}
var promise = Promise.resolve();
promise.then(taskA)
.then(taskB)
.catch(onRejected)
.then(finalTask);
TaskA
TaskB
FinalTask
onRejected
362.
30
function taskA(){
console.log('Task A');
throw new Error('throw Error @ Task A');
}
function taskB(){
console.log('Task B');
}
function onRejected(error){
console.log('Catch Error: A or B', error);
}
function finalTask(){
console.log('Final Task');
}
var promise = Promise.resolve();
promise.then(taskA)
.then(taskB)
.catch(onRejected)
.then(finalTask);
TaskA
TaskB
FinalTask
onRejected
function taskA(){
console.log('Task A');
return Promise.reject(new Error(…));
}
382.
32
function doubleUp(value){
return value * 2;
}
function increment(value){
return value + 1;
}
function output(value){
console.log(value);
}
var promise = Promise.resolve(1);
promise.then(increment)
.then(doubleUp)
.then(output);
increment
doubleUp
output
1
2
4
392.
33
function doubleUp(value){
return value * 2;
}
function increment(value){
return value + 1;
}
function output(value){
console.log(value);
}
var promise = Promise.resolve(1);
promise.then(increment)
.then(doubleUp)
.then(output);
increment
doubleUp
output
1
2
4
반환
469.
35
function ajax(URL, callback){
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function(){
if(req.status === 200){
callback(null, req.responseText);
}else{
callback(
new Error(req.statusText),
req.response
);
}
};
req.onerror = function(){
callback(new Error(req.statusText));
};
req.send();
}
function jsonify(callback, error, value){
var result;
if(error){
callback(error, value);
}else{
try{
result = JSON.parse(value);
callback(null, result);
}catch(err){
callback(err, value);
}
}
}
계속
488.
36
var request = {
cards : function(callback){
return ajax('/api/cards',
jsonify.bind(null, callback));
},
insurances : function(callback){
return ajax('/api/insurances',
jsonify.bind(null, callback));
}
};
function all(requests, record, callback){
var req;
if(requests.length === 0){
return callback(null, record);
}
req = requests.shift();
req(function(error, value){
if(error){
callback(error, value);
}else{
record.push(value);
all(requests, record, callback);
}
});
}
all([request.cards, request.insurances], [],
function(error, value){
if(error){
console.log(error);
}else{
console.log(value);
}
});
536.
38
function ajax(URL){
return new Promise(function(resolve, reject){
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function(){
if(req.status === 200){
resolve(req.responseText);
}else{
reject(new Error(req.statusText));
}
};
req.onerror = function(){
reject(new Error(req.statusText));
};
req.send();
})
}
var request = {
cards : function(){
return ajax('/api/cards')
.then(JSON.parse)
},
insurances : function(){
return ajax('/api/insurances')
.then(JSON.parse)
}
};
560.
39
function all(){
var record = [];
function recording(value){
record.push(value);
return record;
}
return request.cards().then(recording)
.then(request.insurances).then(recording);
}
all().then(function(value){
console.log(value);
}).catch(function(error){
console.log(error);
});
601.
var promise = Promise.reject(new Error('message'));
promise.catch(function(error){
console.log(error.message);
});
var promise = Promise.reject(new Error('message'));
promise['catch'](function(error){
console.log(error.message);
});
var promise = Promise.reject(new Error('message'));
promise.then(undefined, function(error){
console.log(error.message);
});
ECMAScript3에서는
682.
function timer(delay){
return new Promise(function(resolve){
setTimeout(function(){
resolve(delay);
}, delay);
})
}
var start = Date.now();
Promise.all([
timer(1),
timer(32),
timer(64),
timer(128)
]).then(function(values){
console.log(Date.now() - start + 'ms');
console.log(values);
});
734.
44
function timer(delay){
return new Promise(function(resolve){
setTimeout(function(){
resolve(delay);
}, delay);
})
}
var start = Date.now();
Promise.race([
timer(1),
timer(32),
timer(64),
timer(128)
]).then(function(values){
console.log(Date.now() - start + 'ms');
console.log(values);
});
771.
47
var promise = new Promise(function(resolve){
console.log('inner promise');
resolve(42);
});
promise.then(function(value){
console.log(value);
});
console.log('outer promise');
노트
876.
48
function onReady(callback){
var readyState = document.readyState;
if(readyState === 'interactive' ||
readyState === 'complete'){
callback();
}else{
window.addEventListener(
'DOMContentLoaded', callback
);
}
}
onReady(function(){
console.log('DOM fully loaded and parsed');
});
console.log('starting...');
if(readyState === 'interactive' ||
readyState === 'complete'){
setTimeout(fn, 0)
}else{
function onReady(){
return new Promise(function(resolve){
var readyState = document.readyState;
if(readyState === 'interactive' ||
readyState === 'complete'){
resolve();
}else{
window.addEventListener(
'DOMContentLoaded',
resolve);
}
});
}
onReady().then(function(){
console.log('DOM fully loaded and parsed');
});
console.log('starting...');
922.
50
var promise = new Promise(function(resolve){
resolve(100);
});
var thenPromise = promise.then(function(value){
console.log(value);
});
var catchPromise = thenPromise.catch(function(error){
console.log(error);
});
console.log(promise === thenPromise);
console.log(thenPromise === catchPromise);
onFulfilled
onRejected
onRejected
promise object promise object
value
error error
then catch
945.
51
var promise = new Promise(function(resolve){
resolve(100);
});
promise.then(function(value){
return value * 2;
});
promise.then(function(value){
return value * 2;
});
promise.then(function(value){
console.log(value); // 100
});
var promise = new Promise(function(resolve){
resolve(100);
});
promise.then(function(value){
return value * 2;
}).then(function(value){
return value * 2;
}).then(function(value){
console.log(value); // 100 * 2 * 2
});
function anAsyncCall(){
var promise = Promise.resolve();
promise.then(function(){
// something do...
});
return promise;
}
946. 예외 처리가 되지 않는 onRejected
예외 처리가 되지 않는 경우
then()을
959. 예외 처리가 되지 않는 onRejected
예외 처리가 되지 않는 경우
then()을
971.
53
Promise.resolve(30).then(function(value){
throw new Error(value);
}, function(error){
console.log('BAD');
console.log(error);
});
Promise.resolve(20).then(function(value){
throw new Error(value);
}).catch(function(error){
console.log('GOOD');
console.log(error);
});
Promise.resolve(10).then(function(value){
throw new Error(value);
}).then(undefined, function(error){
console.log('OK');
console.log(error);
});
1010.
55
some().then(function(){
// do something...
}).then(function(){
// do something...
}).then(function(){
// do something...
}).then(function(){
// do something...
}).catch(function(){
// do something...
});
1029.
56
커넥터 로직
비즈니스 로직
엔티티 로직
서비스 로직
DAO 로직
스토리지
엔티티
(DTO)
DAO
커넥터
비즈니스
서비스
값 객체
1083.
60
var Stores = function(connector){
this._connector = connector;
};
Stores.prototype = {
findAll : function(){
var self = this;
return new Promise(function(resolve){
var stores = self._connector.where();
resolve(stores.items);
})
},
findBy : function(id){
var self = this;
return new Promise(function(resolve, reject){
var store = self._connector.get(parseInt(id, 10));
if(store){
resolve(store);
}else{
reject(new Error('Not Found.'));
}
});
}
};
module.exports = Stores;