주의! 모든 콜백이 비동기인 것은 아님
> [1,2,3].map(x => x*x)
[ 1, 4, 9 ]
// readFile.js
const fs = require('fs') // Node.js 내장 모듈
fs.readFile('./calc.js', 'utf8', (err, data) => {
console.log(data)
})
console.log('done!')
// readFileSync.js
const fs = require('fs') // Node.js 내장 모듈
const data = fs.readFileSync('./calc.js', 'utf8')
console.log(data)
console.log('done!')
$ # hello-npm 폴더 안에서 실행
$ npm install --save request
// 유저 이름, 저장소, 할당된 이슈 갯수 출력하기
const request = require('request')
const apiUrl = 'https://api.github.com'
const option = {
json: true,
auth: {
'user': 'username',
'pass': 'password',
},
headers: {
'User-Agent': 'request'
}
}
request.get(`${apiUrl}/user`, option, function (error, response, body) {
const name = body.name
if (error) console.error(error)
// 콜백 안에 콜백
request.get(`${apiUrl}/user/repos`, option, function (error, response, body) {
if (error) console.error(error)
const repoNames = body.map(item => item.name)
// 콜백 안에 콜백 안에 콜백
request.get(`${apiUrl}/issues`, option, function (error, response, body) {
if (error) console.error(error)
const issueNum = body.length
console.log(`name: ${name}`)
console.log('repos:')
repoNames.forEach(name => {
console.log(name)
})
console.log(`num of assigned issues: ${issueNum}`)
})
})
})
비동기 작업의 결과를 담는 객체
정확히 언제가 될지 모르지만, 결국 성공 또는 실패의 상태를 갖게 됨
// tenSec.js
module.exports = function tenSec(value) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(value)
}, 10000)
})
}
// REPL
> const tenSec = require('./tenSec')
> const p = tenSec(1)
> p // 만든지 10초가 지나기 전
Promise {
[pending],
...
> p // 만든지 10초가 지난 후
Promise {
1,
...
> tenSec('hello promise').then(value => {
... console.log(value)
... })
Promise { // `then`은 Promise를 반환
[pending],
...
> // 10초 후
'hello promise'
// chaining.js
const tenSec = require('./tenSec')
tenSec('hello promise')
.then(value => {
console.log(value)
return 1 // 위 `.then`은 값이 1인 Promise를 반환함
})
.then(value => {
console.log(value)
return tenSec('new promise') // Promise도 반환할 수 있음
})
.then(value => {
console.log(value)
})
.then(() => {
throw new Error('error in promise')
})
.catch(err => {
console.error(err)
})
.then(() => { // 에러 처리 이후에도 코드 실행 가능
console.log('done')
})
// readfilePromise.js
const {promisify} = require('util') // Node.js 8.0.0부터 추가됨
const fs = require('fs')
const readFile = promisify(fs.readFile)
readFile('./calc.js', 'utf8')
.then(data => {
console.log(data)
})
.catch(err => {
console.error(err)
})
이미 resolve 된 Promise에도 콜백을 실행할 수 있음
> const resolved = Promise.resolve(1)
> resolved.then(v => console.log(v))
`.then`에 넘겨진 콜백은 무조건 다음 루프에 실행됨
> (function() {
... Promise.resolve(1).then(v => console.log(v))
... console.log('done!')
... })()
/* 출력:
done!
1
*/
// npm install --save request-promise
const rp = require('request-promise')
const apiUrl = 'https://api.github.com'
const option = {
json: true,
auth: {
'user': 'username',
'pass': 'password',
},
headers: {
'User-Agent': 'request'
}
}
const userPromise = rp.get(`${apiUrl}/user`, option)
const reposPromise = rp.get(`${apiUrl}/user/repos`, option)
const issuesPromise = rp.get(`${apiUrl}/issues`, option)
// 배열 내의 모든 Promise 객체가 완료되었을 때
// resolve 되는 Promise를 만든다.
Promise.all([userPromise, reposPromise, issuesPromise])
.then(([user, repos, issues]) => {
console.log(`name: ${user.name}`)
console.log('repos:')
repos.forEach(repo => {
console.log(repo.name)
})
console.log(`num of assigned issues: ${issues.length}`)
})
const tenSec = require('./tenSec')
async function resolveAfterTenSec() {
await tenSec()
return 1
}
resolveAfterTenSec().then(value => {
console.log(value)
})
// readfileAsync.js
const {promisify} = require('util') // Node.js 8.0.0부터 추가됨
const fs = require('fs')
const readFile = promisify(fs.readFile)
async function readFileAsync() {
try {
const data = await readFile('./calc.js', 'utf8')
console.log(data)
} catch (e) {
console.error(e)
}
}
readFileAsync()