1. Intro Promises
- 자바스크립트 대표적 비동기 로직: http의 요청/응답, 파일을 읽고 쓰는 파일 입/출력 등
- 비동기로 처리되는 작업들은 흐름을 예측하기 어려움 => 예측하기 쉬운 흐름으로 만드는게 비동기 처리! (콜백, 프로미스, 에이싱크 어웨잇)
- 스프린트 폴더의 example 간단한 예시들
- 이해하고 번호 순대로 exercise 진행
- callback:
- getDataFromFile: 파일의 내용을 읽어와서 결과를 콜백으로 넘겨주는 함수 만들기
- getBodyFromGetRequest: http 응답의 body를 콜백으로 넘겨주는 함수 만들기
- promiseConstructor: 콜백과 같지만 프로미스를 이용
- promisification: util을 이용해서 콜백으로 작성되어 있는 함수들을 프로미스로 변환하기
- basicChaning: 두 가지 이상의 비동기 작업들을 연속적으로 처리하기
- 파일에서 읽어 오는 작업
- 읽어온 결과를 가지고 다시 요청을 하는 작업
- asyncAwait: basicChanig에서 했던 작업을 async await작업으로 리팩토링
2. 자바스크립트 비동기 처리와 콜백 함수[캡틴판교]
- 비동기처리: 특정 코드의 연산이 끌날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성을 의미
비동기 처리의 첫 번째 사례 - 제이쿼리 ajax
- tableData에 response가 담길 것으로 예상되지만 undefined가 담김. 그 이유는 $.get()으로 데이터를 요청하고 받아올 때까지 기다려주지 않고 다음 코드를 실행하기 때문
function getData() {
var tableData;
$.get('https://domain.com/products/1', function(response) {
tableData = response;
});
return tableData;
}
console.log(getData());
비동기 처리의 두 번째 사례 - Web API setTimeout()
- setTimeout()도 비동기 방식으로 처리되므로 3초를 기다렸다가 다음 코드를 실행하는 것이 아니라 일단 setTimeout()을 실행하고 나서 다음 코드인 console.log('Hello Again') 으로 넘어감
- 따라서 Hello, Hello Again가 출력되고 3초 뒤에 Bye가 출력됨
console.log('Hello');
setTimeout(function() {
console.log('Bye');
}, 3000);
console.log('Hello Again');
콜백 함수로 비동기 처리 방식의 문제점 해결하기
- 위와 같이 undefined 등의 문제를 해결하기 위해 콜백 함수를 이용함
- 위의 ajax 사례를 콜백 함수를 이용하는 코드로 개선하면 아래와 같음
function getData(callbackFunc) {
$.get('https://domain.com/products/1', function(response) {
callbackFunc(response);
});
}
getData(function(tableData) {
console.log(tableData);
});
3. 자바스크립트 Promise 쉽게 이해하기[캡틴판교]
- Promise: 자바스크립트 비동기 처리에 사용되는 객체
- 프로미스는 서버에서 받아온 데이터를 화면에 표시할 때 사용
프로미스 코드 - 기초
- 콜백 함수와 프로미스의 비교
- new Promise(), resolve(), then()와 같은 프로미스 API 구조로 변경
function getData(callbackFunc) {
$.get('url 주소/products/1', function (response) {
callbackFunc(response);
});
}
getData(function (tableData) {
console.log(tableData);
});
function getData(callback) {
return new Promise(function (resolve, reject) {
$.get('url 주소/products/1', function (response) {
resolve(response);
});
});
}
getData().then(function (tableData) {
console.log(tableData);
});
프로미스의 3가지 상태(states)
- 상태는 프로미스의 처리 과정을 의미
- Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
- Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
- Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
프로미스 코드 - 쉬운 예제
- 서버에서 제대로 응답을 받으면 resolve() 메서드를 호출하고, 응답이 없으면 reject() 메서드를 호출
- 호출된 메서드에 따라 then()이나 catch()로 분기하여 데이터 또는 오류를 출력
function getData() {
return new Promise(function (resolve, reject) {
$.get('url 주소/products/1', function (response) {
if (response) {
resolve(response);
}
reject(new Error("Request is failed"));
});
});
}
getData().then(function (data) {
console.log(data);
}).catch(function (err) {
console.error(err);
});
여러 개의 프로미스 연결하기 (Promise Chaining)
- 프로미스의 또 다른 특징은 여러 개의 프로미스를 연결하여 사용할 수 있다는 점
new Promise(function(resolve, reject){
setTimeout(function() {
resolve(1);
}, 2000);
})
.then(function(result) {
console.log(result);
return result + 10;
})
.then(function(result) {
console.log(result);
return result + 20;
})
.then(function(result) {
console.log(result);
});
프로미스의 에러 처리 방법
- then()의 두번째 인자로 에러를 처리하는 방법과 catch()를 쓰는 방법이 존재
- 가급적이면 에러 처리를 위해 catch()를 쓰는 편이 좋음
4. Node.js에서 Request.js 사용하기
https://medium.com/harrythegreat/node-js%EC%97%90%EC%84%9C-request-js-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-28744c52f68d
- 브라우저에서 자바스크립트를 쓴다면 fetch라는 내장 모듈이 있지만 Node.js에서 가장 많이 쓰는 HTTP 라이브러리는 request.js
const request = require('request');
request('http://www.google.com', function (error, response, body) {
console.error('error:', error);
console.log('statusCode:', response && response.statusCode);
console.log('body:', body);
});
request.get({ uri: "http://www.google.com" }, function (error, response, body) {
console.error('error:', error);
console.log('statusCode:', response && response.statusCode);
console.log('body:', body);
});
const options = {
uri: "http://www.google.com",
qs: {
page: 5
}
};
request(options, function (error, response, body) {
console.error('error:', error);
console.log('statusCode:', response && response.statusCode);
console.log('body:', body);
});
const options = {
uri: 'http://google.com',
method: 'POST',
form: {
key: 'value',
key: 'value',
}
}
request.post(options, function (err, httpResponse, body) { })
const options = {
uri: 'http://google.com',
method: 'POST',
body: {
key: value
},
json: true
}
5. fs.readFile()
fs.readFile('/etc/passwd', (err, data) => {
if (err) throw err;
console.log(data);
});
fs.readFile('/etc/passwd', 'utf8', callback);