๐ ์ฐ๋ฆฌ๊ฐ ์ฝ๋ฐฑ์ ํด์ผํ๋ ์ด์
๋ฐ๋ณตํด์ผํ ๋๋ง๋ค ๊ฐ์ ์์ ์ฌ๋ฌ๋ฒ ์จ์ผํ๋ค.
setTimeout(() => {
document.body.style.backgroundColor = 'red';
}, 1000)
setTimeout(() => {
document.body.style.backgroundColor = 'orange';
}, 2000)
setTimeout(() => {
document.body.style.backgroundColor = 'yellow';
}, 3000)
setTimeout(() => {
document.body.style.backgroundColor = 'green';
}, 4000)
setTimeout(() => {
document.body.style.backgroundColor = 'blue';
}, 5000)
๐ ๋น์ทํ ์ญํ ์ ํ๋ ์ฝ๋๋ฅผ ๋ฐ๋ณตํด์ ์ฐ๊ณ ์๋ค๋ ๋จ์ ์ด ์๋ค.
์ฒซ๋ฒ์งธ์ 1์ด ํ, ๋๋ฒ์งธ์ 1์ด ํ ์ด๋ฐ์์ผ๋ก ์๋์ผ๋ก ๋์๊ฐ๋ ํ๋ก๊ทธ๋จ์ด ํ์ํด!
์ค์ฒฉ์ ํ์ฉํด์ ์ธ ์ ์๋ค.
setTimeout(() => {
document.body.style.backgroundColor = 'red';
setTimeout(() => {
document.body.style.backgroundColor = 'orange';
setTimeout(() => {
document.body.style.backgroundColor = 'yellow';
setTimeout(() => {
document.body.style.backgroundColor = 'green';
setTimeout(() => {
document.body.style.backgroundColor = 'blue';
}, 1000)
}, 1000)
}, 1000)
}, 1000)
}, 1000)
๐ ์ผ๋ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ๊ณ , ๋ค๋ฅธ ํจ๊ณผ๋ฅผ ์ฃผ๊ณ ์ถ๋ค๋ฉด!
์ถ๊ฐ๊ณต๋ถ setTimeout ํจ์์ ๋ํด ์์๋ณด๊ธฐ
2022.05.28 - [JavaScript] - TIL) ์๋ฐ์คํฌ๋ฆฝํธ ๋น๋๊ธฐ์ setTimeout
const delayedColorChange = (newColor,delay,doNext) => {
setTimeout(() => {
document.body.style.backgroundColor = newColor;
doNext();
}, delay)
}
delayedColorChange('red',1000,() => {
delayedColorChange('orange',1000,() => {
delayedColorChange('yellow',1000,() => {
delayedColorChange('green',1000,() => {
delayedColorChange('blue',1000,() => {
})
})
})
})
});
๐ ์๊ฐ์ ๋ชจ๋ฅด๋ ๊ฒฝ์ฐ (๊ฐ์ง ์ฝ๋์ด๊ฑฐ๋ ์กด์ฌํ์ง ์๋ ํจ์์ธ ๊ฒฝ์ฐ)
searchMoviesAPI('amadeus', () => {
saveToMyDB(movies, () => {
// if it works, run this
}, () => {
// if it doesn't work, run this
})
},() => {
// if API is down, or request failed
})
โฌ๏ธ ์ด๊ฒ ์ผ๋ฐ์ ์ธ ๊ฑฐ๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๊ธฐ๊ฐ ์๋ํ ์ ๋ ์๊ณ ,
์ธํฐ๋ท์ด ๋ฉ์ถ๊ฑฐ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์กด์ฌํ์ง ์๊ฑฐ๋ ๊ถํ์ด ์๊ฑฐ๋, ์ฉ๋์ด ์๋ค๋ฉด ์๋ํ์ง ์๋๊ฑฐ๋ค.
๋ฐ๋ผ์ ๋ ๊ฐ์ง ๊ฐ๋ฅํ ๊ฒฐ๊ณผ์ ๋ํด ์์ํด์ผํ๋ค.
๋ช ์ด ํ ๋ฐ์ํ ๋๊น์ง ์ ์๊ฐ ์๋ค.
๊ฒฐ๋ก , ์ฝ๋ฐฑ์ ์ค๋ณต์ ์ข์ง ์์ง๋ง, ์ค์ ๋ก๋ ํ๋ ์ด์์ ์ฝ๋ฐฑ์ด ์๋ ๊ฒฝ์ฐ๊ฐ ํํ๋ค!
์ฝ๋ฐฑ ์ค๋ณต (์ฝ๋ฐฑ ํฌ)์ ๋ถ๊ฐํผํ๋ค!!
์ด๋ฐ ์ด๋ ค์์ ํด๊ฒฐํ๊ธฐ ์ํด ๋์จ ๊ฒ์ด ๋ฐ๋ก Promise์ ๋น๋๊ธฐ ํจ์!!!
Promise๋ ์ด๋ค ์ฐ์ฐ, ๋น๋๊ธฐ ์ฐ์ฐ์ด ์ต์ข ์ ์ผ๋ก ์๋ฃ ํน์ ์ฑ๊ณตํ๋์ง ์คํจํ๋์ง ์๋ ค์ฃผ๋ ๊ฐ์ฒด์ด๋ค.
const fakeRequestCallback = (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)
}
fakeRequestCallback('books.com', function() {
console.log('IT WORKED!!')
}, function() {
console.log('ERROR!!')
})
โฅ๋๋ค์ด๊ธฐ ๋๋ฌธ์, ์คํจ, ์ฑ๊ณต ๋ ์ค์ ํ๋์ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค.
์ถ๊ฐํ์ต
Math.random()
const fakeRequestCallback = (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)
}
fakeRequestCallback('books.com',
function(response) {
console.log('IT WORKED!!')
console.log(response)
}, function(err) {
console.log('ERROR!!', err)
})
โฅ๋๋ค์ด๊ธฐ ๋๋ฌธ์, ์คํจ, ์ฑ๊ณต ๋ ์ค์ ํ๋์ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค.
๐ books.com ์ page2 ์์ฒญ๋ ์๋ค๊ณ ๊ฐ์ ํ๋ค๋ฉด!
const fakeRequestCallback = (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)
}
fakeRequestCallback('books.com/page1',
function (response) {
console.log('IT WORKED!!');
console.log(response);
fakeRequestCallback(
'books.com/page2',
function (response) {
console.log('IT WORKED AGAIN!!');
console.log(response);
},
function (err) {
console.log('ERROR!!(2nd request)', err);
}
);
},
function (err) {
console.log('ERROR!!', err);
}
);
โฅ ์ ์ ์ค ํ๋์ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค.
** ๋ ๋ฒ์งธ ์์ฒญ์ ๋ณด๋ด๋๋ก ๋ง๋ค๊ธฐ ์ํด์๋ ์ฒซ๋ฒ์งธ ์ฑ๊ณต ์ฝ๋ฐฑ ์์ ๋ผ์๋ฃ์ด์ผํ๋ค!
const fakeRequestCallback = (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)
}
fakeRequestCallback('books.com/page1',
function(response) {
console.log('IT WORKED!!')
console.log(response)
fakeRequestCallback('books.com/page2',
function(response) {
console.log('IT WORKED AGAIN!!')
console.log(response)
fakeRequestCallback('books.com/page3',
function (response) {
console.log('IT WORKED AGAIN (3rd request)!!')
console.log(response)
},
function (err) {
console.log('ERROR!!(3rd request)', err)
})
},
function (err) {
console.log('ERROR!!(2nd request)', err)
})
}, function(err) {
console.log('ERROR!!', err)
})
โฅ ์ด๋์๋ ์คํจํ๋ ์๊ฐ, ์ฑ๊ณต ์ฝ๋ฐฑ์ด ์คํ๋์ง ์์์ ๋ค์ ์์ฒญ์ผ๋ก ๋์ด๊ฐ์ง ์๊ณ ์ข ๋ฃํ๋ค.
Promise = ๊ฐ์ด๋ ์ค๋ฅ์ ๋ํ ์ต์ข ๊ฒฐ๊ณผ(์ฝ์)์ด๋ค.
const fakeRequestCallback = (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)
}
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)
})
}
const request = fakeRequestPromise('yelp.com/api/coffee');
request
.then(() => {
console.log('IT WORKED!!!')
})
.catch(() => {
console.log('OH NO, ERROR')
})
๐ ์ฝ๋ฐฑ ๋ฒ์ ์ ์ฝ๋์ ๋๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋์ถํ๋ค.
๐ request๋ ๊ฐ์ฒด์ด๋ค. .then๊ณผ .catch๋ request์ ๋ฉ์๋์ด๋ค. ๋ ๋ค ๊ฐ๊ฐ ์ฝ๋ฐฑ์ ๋ฃ๋๋ค.
๋ ์ค ํ๋๋ง ์คํ์ด ๋ ํ ๋ฐ, Promise๊ฐ resolve๋๋ฉด () => {console.log('IT WORKED!!!')} ํจ์๊ฐ ์คํ๋๊ณ ,
reject๋๋ฉด () => {console.log('OH NO, ERROR')} ํจ์๊ฐ ์คํ๋๋ค.
fakeRequestPromise('yelp.com/api/coffee/page1')
.then(() => {
console.log('IT WORKED!!! (page1)')
fakeRequestPromise('yelp.com/api/coffee/page2')
.then(() => {
console.log('IT WORKED!!! (page2)')
fakeRequestPromise('yelp.com/api/coffee/page3')
.then(() => {
console.log('IT WORKED!!! (page3)')
})
.catch(() => {
console.log('OH NO, ERROR (page3)')
})
})
.catch(() => {
console.log('OH NO, ERROR (page2)')
})
})
.catch(() => {
console.log('OH NO, ERROR (page1)')
})
โฅ page1 ์์ฒญ ์ฑ๊ณต ํ page2, page3 ์์ฒญํ๋ ํ๋ก๊ทธ๋จ์ promise๋ก ๊ตฌํํ๊ธฐ
๐ promise ๊ฐ callback ๋ณด๋ค ๋์ ์ด์
fakeRequestPromise('yelp.com/api/coffee/page1')
.then(() => {
console.log('IT WORKED!! (page1)')
return fakeRequestPromise('yelp.com/api/coffee/page2') // Promise๋ฅผ ๋ฐํํ๊ณ
})
.then(() => { // .then์ผ๋ก ๊ทธ ๋ฐํ์ ํธ์ถํ๋ค.(๊ทธ๋์ ์ค์ฒฉ ํ์์์)
console.log('IT WORKED!! (page2)')
return fakeRequestPromise('yelp.com/api/coffee/page3')
})
.then(() => {
console.log('IT WORKED!! (page3)')
})
.catch(() => { // catch๋ ํ๋๋ง ์์ผ๋ฉด ๋๋ค!!
console.log('OH NO, A REQUEST FAILED')
})
โฅ Promise ๋ .then ์์์ ๋ ์์ ์๊ฒ Promise๋ฅผ ๋ฐํํ ์ ์๋ค. ์ฆ, ์ค์ฒฉ์์ด ๋ค๋ฅธ .then๋ค์ ์ฐ์์ํฌ ์ ์๋ค.
์ด๋์๋ Promise๊ฐ reject๋๋ฉด, ์ ๋ถ ๋ฌด์ํ๊ณ ๋ฐ๋ก catch๋ก ๊ฐ๋ค. (.then ์ฝ๋ฐฑ ์์์ Promise๋ฅผ ๋ฐํํ๊ธฐ ๋๋ฌธ์ด๋ค.)
Promise์ ๋ํด ์์๋ ๊ฒ์ ๊ฐ์ผ๋ก resolve ๋๋ reject๋๋ค๋ ๊ฒ์ด๋ค.
์ฌ๊ธฐ ์ฝ๋ฐฑ์๋ ๋งค๊ฐ๋ณ์๊ฐ ์๋ค.
ํ์ง๋ง promise๋ ์ ๋ฌ๋ฐ์ ๊ฐ์ผ๋ก resolve ๋๋ reject๋๋ค. (then์ด ๊ทธ ๊ฐ์ ๋ฐ๋๋ค.)
์ค์ ์์ฒญ์ ์์ฑํ๋ค๋ฉด ๋ฐ์ดํฐ๊ฐ ํ์ํ๋ค. ๐ ๋งค๊ฐ๋ณ์์ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฃ๊ณ ์ถ๋ ฅํด๋ณด์
fakeRequestPromise('yelp.com/api/coffee/page1')
.then((data) => {
console.log('IT WORKED!! (page1)')
console.log(data)
return fakeRequestPromise('yelp.com/api/coffee/page2')
})
.then((data) => {
console.log('IT WORKED!! (page2)')
console.log(data)
return fakeRequestPromise('yelp.com/api/coffee/page3')
})
.then((data) => {
console.log('IT WORKED!! (page3)')
console.log(data)
})
.catch((err) => {
console.log('OH NO, A REQUEST FAILED')
console.log(err)
})
์ Promise ์์ฑ๋ฒ
new Promise((resolve, reject) => {
resolve();
})
โฅ PromiseState: 'fulfilled'
new Promise((resolve, reject) => {
reject();
})
โฅ PromiseState: 'rejected'
new Promise((resolve, reject) => {
})
โฅ PromiseState: 'pending'
Promise์ ์ธ ๊ฐ์ง ์ํ
pending: ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ์ค
fulfilled: ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ ์์ ์ผ๋ก ๋๋ฌ๊ณ ๊ฒฐ๊ณผ๊ฐ์ ๊ฐ์ง๊ณ ์์
rejected: ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ๋น์ ์์ ์ผ๋ก ๋๋ฌ์
๐ ๊ฐ์ง ์์ฒญ ํจ์๋ฅผ ๋ง๋ค์ด๋ณด์.
const fakeRequest = (url) => {
return new Promise((resolve, reject) => {
const rand = Math.random();
setTimeout(() => {
if(rand < 0.7){
resolve('YOUR FAKE DATA HERE');
}
reject('REQUEST ERROR');
}, 1000)
})
}
fakeRequest('/dogs/1')
.then((data) => {
console.log('DONE WITH REQUEST!')
console.log('data is: ', data)
})
.catch((err) => {
console.log('OH NO!',err)
})
โฅ ๋ ์ค ํ๋์ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค.
** ์ Promise๋ฅผ ๋ง๋ค๋ ค๋ฉด, ํจ์์ ๋ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ฌํด์ผํ๋ค.
์ฒซ๋ฒ์งธ๋ Promise๋ฅผ resolveํ ํจ์, ๋๋ฒ์งธ๋ Promise๋ฅผ rejectํ ํจ์๋ค.
Callback ํจ์๋ฅผ Promise๋ก ๋ง๋ค์ด๋ณด์!
const delayedColorChange = (newColor,delay,doNext) => {
setTimeout(() => {
document.body.style.backgroundColor = newColor;
doNext();
}, delay)
}
delayedColorChange('red',1000,() => {
delayedColorChange('orange',1000,() => {
delayedColorChange('yellow',1000,() => {
delayedColorChange('green',1000,() => {
delayedColorChange('blue',1000,() => {
})
})
})
})
});
๐ ์ฝ๋ฐฑ ํจ์๋ก ์ด ์ฝ๋๋ฅผ Promise๋ฅผ ์ฌ์ฉํ ์ฝ๋๋ก ๋ฐ๊ฟ๋ณด์!!
delayedColorChange ํจ์๊ฐ ์ฝ๋ฐฑ์ ์ ๋ฌํ์ง ์๊ณ Promise๋ฅผ ๋ฐํํ๊ฒ ํ๋ฉด ๋๋ค.
const delayedColorChange = (color, delay) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
document.body.style.backgroundColor = color;
resolve();
}, delay)
})
}
โฅ ์์ callbackํจ์์ ๋น๊ตํด๋ณด๋ฉด, ๋ง์ ๊ฒ์ ์ ๋ฌํ๊ฑฐ๋ ์ค์ฒฉํ์ง ์์๋ ๋๋ค๋ ์ ์์ ๊ฐ์น๊ฐ ์๋ค.
delayedColorChange('red', 1000)
delayedColorChange('orange', 1000)
// ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ์ ๋์ถํ๋ค.
delayedColorChange('red', 1000)
.then(() => {
delayedColorChange('orange', 1000)
})
// ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ์ ๋์ถํ๋ค.
delayedColorChange('red', 1000)
.then(() => {
return delayedColorChange('orange', 1000)
})
// ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ์ ๋์ถํ๋ค.
delayedColorChange('red', 1000)
.then(() => delayedColorChange('orange', 1000))
.then(() => delayedColorChange('yellow', 1000))
.then(() => delayedColorChange('green', 1000))
.then(() => delayedColorChange('blue', 1000))