실제로 구현하는 코드는 아니지만, URL을 입력하면 setTimeout
을 메소드를 실행하여 각각의 랜덤 상황에 따라 pending
, resolved
, rejected
를 반환하는 fakeRequest를 만들어보겠습니다. 물론, 중요한 점은 콜백 지옥을 해결할 Promise
를 이용한다는 점입니다.
더욱 자세한 내용은 MDN 공식문서 Promise를 참고해주시면 됩니다.
const fakeRequest = (url, success, failure) => {
const delay = Math.floor(Math.random() * 4500) + 500;
setTimeout(() => {
if (delay > 4000) {
failure('Connection Timeout :(')
} else {
success(`Here is your fake data from ${url}`)
}
}, delay)
}
콜백 함수를 사용하여 구현한 코드라는 점은 알 수 있겠죠?
fakeRequest('books.com/page1', function(response) {
console.log('IT WORKED!!')
console.log(response)
fakeRequest('books.com/page2', function(response) {
console.log('IT WORKED!!')
console.log(response)
}), function(err) {
console.log('ERROR!!', err)
}
}, function(err) {
console.log('ERROR!!', err)
})
위의 코드를 이용하여 success
, failure
의 경우로 나뉘었을 때 어떻게 결과값을 받아올 수 있는지 fakeRequest
함수를 nesting하여 호출해보았습니다. 한 눈에 봐도 이미 콜백 지옥이 시작되었구나를 짐작할 수 있습니다.
A promise is a returned object to which you attatch callbacks, instead of passing callbacks into a function.
Promise
는 콜백을 함수에 전달하는 것이 아닌 붙인 콜백에 반환된 객체입니다.
const fakeRequestPromise = (url) => {
return new Promise((resolve, reject) => {
const delay = Math.floor(Math.random() * (4500)) + 500;
setTimeout(() => {
if (delay > 4000) {
reject('Connection Timeout :(')
} else {
resolve(`Here is your fake data from ${url}`)
}
}, delay)
})
}
Promise
라는 객체를 반환하는 함수라는 점을 바로 알 수 있습니다. 그 Promise
내에는 위에서 구현한 setTimeout
의 로직이 포함되어 있습니다. 그렇다면 이 함수를 호출할 때에는 어떻게 될까요?
const request = fakeRequestPromise('yelp.com/api.coffee/page1')
request
.then(() => {
console.log('PROMISE FULFILLED!')
console.log('IT WORKED!!')
})
정의한 함수를 request
라는 변수에 넣습니다. 이는 Promise
라는 객체를 반환할 것입니다. 그리고 request.then()
이라는 request
의 property에 콜백 함수를 넣습니다. 이는 resolve
, 연산이 성공적으로 완료되었다면 실행할 콜백 함수입니다.
const request = fakeRequestPromise('yelp.com/api.coffee/page1')
request
.then(() => {
console.log('PROMISE FULFILLED!')
console.log('IT WORKED!!')
})
.catch(() => {
console.log('PROMISE REJECTED!')
console.log('OH NO, ERROR!!!')
})
반대로 연산이 실패한 경우, catch
라는 속성을 이용하여 위와 같이 콜백 함수를 넣어주면 되는 것입니다.
이번에도 1번의 예제와 마찬가지로 성공할 경우, 또 다른 페이지를 반복해서 요청하는 함수를 nesting하여 호출해보도록 하겠습니다. 이번에는 request
라는 변수에 저장하지 않는 방법으로 진행합니다.
fakeRequestPromise('yelp.com/api.coffee/page1')
.then(() => {
console.log('IT WORKED!! (page1)')
fakeRequestPromise('yelp.com/api.coffee/page2')
.then(() => {
console.log('IT WORKED!! (page2)')
})
.catch(() => {
console.log('OH NO, ERROR!!! (page2)')
})
})
.catch(() => {
console.log('OH NO, ERROR!!! (page1)')
})
조금은 깔끔해보이지만, nesting을 2번이 아닌 5번, 10번을 하게 되다보면 이 코드도 이전과 마찬가지로 복잡해지는 것은 마찬가지일 것 같습니다. 그렇다면 Promise
는 이 문제를 해결하지 못할까요? 다음 글에서 알아보도록 합시다.