Part1. 필기
/*
먼저 promise는 javascript 비동기 처리에 사용되는 객체이다.
promise는 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용한다.
========================================================================
***Q1. Promise 실행 함수의 두 개의 파라미터 resolve 와 reject 는 각각 무엇을 의미하나요?**
**!resolve 와 reject란?**
promise를 통해 new Promise()로 프로미스를 생성한다고 가정하자.
여기서 new Promise에 전달되는 함수는 executor(실행자, 실행 함수) 라고 부른다.
executor은 new Promise가 만들어질 때 자동적으로 실행된다.
executor의 인수 resolve와 reject는 자바스크립트에서 자체 제공하는 콜백이다.
1. resolve(value) — 일이 성공적으로 끝난 경우 그 결과를 나타내는 value와 함께 호출
2. reject(error) — 에러 발생 시 에러 객체를 나타내는 error와 함께 호출
- executor는 상황에 따라 인수로 넘겨준 콜백 중 하나는 반드시 호출해야 한다
=> 따라서 executor는 romise의 상태를 둘 중 하나로 변화시킨다.
**!정리하자면,**
resolve와 reject는 executor의 인수이며 자바스크립트에서 자체 제공하는 콜백이다.
resolve는 일이 성공적으로 끝난 경우 그 결과를 나타내는 value와 함께 호출하고,
reject는 에러 발생 시 에러 객체를 나타내는 error와 함께 호출한다.
==============================================================================
**Q2. Promise.prototype.then 메서드와 Promise.prototype.catch 메서드는 무엇을 리턴하나요?
!프로미스 메서드**
1. .then : .then의 인수인 함수를 실행(이행)한다.
- 이행과 실패의 결과(실행결과,에러)를 모두 받을 수 있다.
2. .catch : 에러가 발생한 경우만 다룬다.
- .catch(f) === .then(null,f) 완전히 일치
- 에러처리는 .then(), .catch() 모두 가능하지만 가급적 .catch()로 에러를 처리하는게 더 효율적이다
(catch가 더 많은 예외 처리 사항을 핸들링 할 수 있기 때문이다.)
3. .finally : 성공,실패 여부와 상관 없이 절차를 마무리한다.
.finally(f) == .then(f, f) 유사
===========================================================================
**Q3. Promise의 세 가지 상태는 각각 무엇이며, 어떤 의미를 가지나요?
!promise의 3가지 상태**
promise엔 3가지 상태(states)가 있다.
-> 여기서 상태란, 프로미스의 처리과정을 의미하며, new Promise()로 프로미스를 생성하고 종료될 때까지 3가지 상태를 갖는다.
1. Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
- new Promise() 메서드를 호출하면 대기(Pending) 상태가 된다.
- new Promise() 메서드를 호출할 때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자로 resolve, reject를 사용할 수 있다.
2. Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
- 콜백 함수의 인자 resolve를 실행하면 이행(Fulfilled) 상태가 된다.
- 이행 상태가 되면 then()을 이용하여 처리 결과 값을 받을 수 있다.
3. Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
- 실패한 이유(실패 처리의 결과 값)를 catch()로 받을 수 있다.
======================================================================
**Q4. await 키워드 다음에 등장하는 함수 실행은 어떤 타입을 리턴할 경우에만 의미가 있나요?
그리고 await 키워드를 사용할 경우, 어떤 값이 리턴되나요?**
참고자료 : https://ko.javascript.info/async-await
**!async와 await**
1. async
async는 function 앞에 위치하고 function 앞에 async를 붙이면 해당 함수는 항상 프라미스를 반환한다.
만약 프라미스가 아닌 값을 반환하더라도 이행 상태의 프라미스(resolved promise)로 값을 감싸 이행된 프라미스가 반환되도록 한다.
=> 즉, async가 붙은 함수는 반드시 프로미스를 반환하고, 프로미스가 아닌 것은 프로미스로 감싸 반환한다.
2. await
1)await 키워드는 async함수 안에서만 동작한다.
`let value = await promise`
2)자바스크립트는 await 키워드를 만나면 프로미스가 처리될 때까지 기다린다. 그리고 그 후 결과가 반환된다.
3)await 키워드 다음 추가 동작코드가 있을 시, await 키워드가 작성된 코드가 동작하고 그 다음에 다음 순서의 코드가 동작한다.
(*)await 키워드의 장점
1.await 키워드는 프로미스가 처리되길 기다리는 동안 엔진이 다른일을 할 수 있기에 -> CPU 리소스가 낭비되지 않는다.
2.await 키워드를 사용하면 promise.then보다 가독성 좋고 쓰기도 쉽다.
(*)await키워드의 주의점
1. async 함수가 아닌 일반 함수엔 사용할 수 없다(문법에러 발생)
2. await는 최상위 레벨 코드에서 작동하지 않는다.
let response = await fetch('/article/promise-chaining/user.json');
let user = await response.json(); //--> 문법에러 발생
-> 하지만 익명 async함수로 감싸면 최상위 레벨 코드에서도 awit를 사용할 수 있다.
(async () => {
let response = await fetch('/article/promise-chaining/user.json');
let user = await response.json();
...
})();
**!정리하자면,**
*function 앞에 async 키워드를 추가하면(async 키워드의 효과)
1. 함수는 언제나 프로미스를 반환하고 2. 함숭수 안에서 await를 사용할 수 있다.
*프로미스에 await 키워드를 붙이면 프로미스가 처리될 때까지 대기 -> 처리 완료되면 조건에 따라
1. 에러발생(예외가 생성됨) 2. 에러 미발생(프로미스 객체의 result 값을 반환한다)
-> async/await를 사용하면 promise.then/catch가 거의 필요 없다.
*/
Part2.
**
const getDataFromFile = function (filePath, callback) {
fs.readFile(filePath, "utf-8", (err, data)=>{
if(err){
callback(err, null);
}else {
callback(null, data);
}
})
};
**
const getDataFromFilePromise = filePath => {
return new Promise((resolve, reject)=>{
fs.readFile(filePath,"utf8", (err, data)=>{
if(err){
reject(err)
}else{
resolve(data);
}
});
})
};
**
const readAllUsersChaining = () => {
return getDataFromFilePromise(user1Path)
.then((user1)=> {
return getDataFromFilePromise(user2Path)
.then((user2)=>{
return `[${user1}, ${user2}]`
});
})
.then((text)=> JSON.parse(text));
};
**
const readAllUsers = () => {
return Promise.all([getDataFromFilePromise(user1Path),getDataFromFilePromise(user2Path)])
.then(([user1, user2])=>{
return `[${user1}, ${user2}]`
})
.then(text => JSON.parse(text));
}
/* 효근님 코드
const readAllUsers = () => {
return Promise.all([getDataFromFilePromise(user1Path),getDataFromFilePromise(user2Path)]
.then((value)=>{
return [JSON.parse(value[0]),JSON.parse(value[1])];
});
}
*/
**
**
const readAllUsersAsyncAwait = async () => {
let user1 = await getDataFromFilePromise(user1Path)
let user2 = await getDataFromFilePromise(user2Path)
let join = `[${user1}, ${user2}]`
let result = JSON.parse(join)
return result;
}
module.exports = {
readAllUsersAsyncAwait
}
Part3.
**
function getNewsAndWeather() {
return fetch(newsURL)
.then(response => response.json())
.then(news => {
return fetch(weatherURL)
.then(response => response.json())
.then(weather => {
return {
/* /data/latest 의 응답 내용과 /data/weather 응답 내용을 합쳐 새로운 객체로 리턴*/
news : news.data,
weather : weather
}
});
})
}
**
function getNewsAndWeatherAll() {
return Promise.all([
fetch(newsURL),
fetch(weatherURL)
])
.then (([news, weather])=> {
return Promise.all([news.json(), weather.json()])
})
.then(([news, weather])=>{
return {
news : news.data,
weather : weather
}
})
}
**
async function getNewsAndWeatherAsync() {
const a = await fetch(newsURL).then(response => response.json())
const b = await fetch(weatherURL).then(response => response.json())
return {news : a.data, weather : b}
}