Promise chaining
Fetch
Promise 를 사용하여 숫자를 차례대로 1, 12, 123 출력해 보자.
.then
을 이어붙여 chaining 을 만들 수 있다.
new Promise((resolve, reject)=> {
resolve('1');
})
.then(result => {
console.log(result);
return result + '2';
})
.then(result => {
console.log(result);
return result + '3';
})
.then(result => {
console.log(result);
return result;
})
// 1 12 123
알 수 있는 점:
{ state "resolved", value: "1" }
인 Promise 객체가 된다. (이러한 객체가 "반환"된다.)then
을 써서 value
를 인자로 받을 수 있다. 이 값으로 필요한 작업을 수행한 후, '12'
를 반환한다. 그러면 이 then
은 { state "resolved", value: "12" }
인 Promise 객체가 된다. (이러한 객체가 "반환"된다.)then
을 써서 value
를 인자로 받는다. 이 값으로 필요한 작업을 수행한 후, '123'
를 반환한다. 그러면 이 then
은 { state "resolved", value: "123" }
인 Promise 객체가 된다. (이러한 객체가 "반환"된다.)이런 식으로 나아간다.
위 코드를 setTimeout
을 활용하여 비동기적으로 만들어보자:
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('1');
}, 2000)
})
.then(result => {
setTimeout(() => {
console.log(result);
return result + '2';
}, 2000)
})
.then(result => {
setTimeout(() => {
console.log(result);
return result + '3';
}, 2000)
})
.then(result => {
setTimeout(() => {
console.log(result);
return result;
}, 2000)
})
// 1 undefined undefined
위 코드가 실패하는 이유:
이미 Setteled 된 Promise 에 return 을 하고 있기 때문에 새로운 비동기 작업을 할 수 없다.
함수의 작동:
'1'
을 넘긴다. '1'
을 출력하도록 등록하고, 그 다음 then 은 result 인자로 undefined
를 받는다.undefined
를 출력하도록 등록하고 다시 그 다음 then 은 undefined
를 인자로 받는다.undefined
를 출력하도록 등록한다.'1'
, undefined
, undefined
가 출력된다.따라서, 1, 12, 123 을 만드려면 then 안에 새로운 promise 객체를 만들어 반환해야 한다.
function print(word) {
return new Promise((resolve, reject)=> {
setTimeout(()=> {
console.log(word);
resolve(word);
}, 2000)
})
}
// print() 는 새로운 promise 객체를 만들어 resolve 후 return 한다.
print('1')
.then((result)=> { return print(result + '2'); })
.then((result)=> { return print(result + '3'); })
// 1 12 123
아까 코드와 다른 점은 매번 unsetteled 한 새 promise 를 만들어 반환하기 때문에, 매번 새로운 비동기 작업을 수행한다. 즉 print()
안에 있는 setTimeout
이 수행되고 resolve 가 될 때까지 return 을 하지 않는다. 따라서 2초마다 순차적으로 값이 나올 수 있다.
then 안에 새로운 Promise 를 만들어 리턴하는 방식은 다수의 비동기 작업을 순서에 맞게 실행하도록 만들어준다.
fetch
함수는 서버에서 데이터를 가져올 때 사용한다.
let promise = fetch(url);
// fetch 함수는 네트워크 요청을 하고 promise 객체를 return 한다.
// 이 Promise 는 response 객체를 resolve 하는데, response 객체 내부의 데이터는 완전히 다운로드되지 않은 상태다.
// 따라서 response 를 보려면 response.text() 메소드를 사용한다.
// .text() 메소드는 text 가 서버에서 완전히 다운로드되면 res.text 를 resolve 하는 promise 를 리턴한다.
fetch(url)
.then(res => res.text())
.then(text => console.log(text))
// res.text() 메소드는 raw json 을 보여준다.
// parse 된 데이터를 보려면 res.json() 메소드를 사용한다.
fetch(url)
.then(res => res.json())
.then(data => console.log(data))
// Github API 를 이용한 예시
fetch('https://api.github.com/users/jhoryong')
.then(res => res.json())
.then(data => console.log(data.name)) // Horyong Jung
Promise Chaining
https://javascript.info/promise-basics