브이로그
2024년 4월 23일 Node.js-promise 본문
콜백 지옥
getUserInfo(userId, (user) => {
getPosts(user.id, (posts) => {
displayPosts(posts)
}, (error) => {
handleError(error)
})
},(error) => {
handleError(error)
})
getUserInfo(userId)
.then((user) => {
return getPosts(user,id)
})
.then((posts) => {
displayPosts(posts)
})
.catch((error) => {
handleError(error)
})
프로미스(Promise)
- 비동기(특정작업이 완료될 때까지 기다리지 않고 다른 작업을 수행할 수 있음) 작업을 다루는 객체
프로미스의 상태
- 대기 : 비동기 작업이 아직 수행되지 않은 상태
- 이행 : 비동기 작업이 성공적으로 완료된 상태 resolve() 호출
- 거부 : 비동기 작업이 실패한 상태 reject()호출
const myPromise = new Promise((resolve, reject) => {
// 비동기 작업 수행
// 작업이 성공하면 resolve() 호출
// 작업이 실해하면 reject() 호출
})
myPromise
.then((result) => {
// 성공했을 때의 처리
})
.catch((error) => {
// 실패했을 때의 처리
})
async / await
- 자바스크립트에서 비동기 코드를 더 쉽게 작성하고 관리할 수 있는 기능
- 비동기 작업이 순차적으로 실행되는 것처럼 코드를 작성할 수 있음
- async 함수는 항상 Promise를 반환, await키워드는 async 함수내에서만 사용
JSON(JavaScript Object Notation)
서버와 클라이언트 간의 HTTP 통신을 위한 포맷
fetch()
- 네트워크를 통해 리소스를 가져오기 위해 사용되는 자바스크립트 API
- 주로 웹 애플리케이션에서 서버와 데이터를 주고 받을 때 사용
- Promise 반환
fetch(접속할 주소)
.then (response => {
응답 데이터를 처리
return response.json() // json형식의 데이터를 반환
})
.then(data => {
// 처리된 데이터를 사용
})
.catch(error => {
// 에러 처리
})
import 사용법
package.json을 생성하고 "type" : "module"을 추가
프로미스라는게 나오기 전에 콜백지옥(div>div>div>div>div...>div)이라는 용어가 있었고 지금도 존재하고 있어
작업을 할려면 하나하나 순서대로 해주는데 프로미스는 다른 작업들을 끝내고 나서 나머지 특정 작업들을 수행하는거야
1. timeout
// 동기식 -> 순서대로 실행 오래걸려도 나머지 코드는 기다린다.
function func1(){
for(let i=0; i<10000000000; i++)
return 10
}
function func2(){
return func1() + 10
}
function func3(){
return func2() + 10
}
console.log('프로그램이 시작됩니다')
const result = func3()
console.log(result)
// 비동기식 -> 오래 걸려도 기다리지 않고 나머지가 먼저 출려됨
function timeout(){
console.log('1번 문장 실행')
setTimeout(() => {
console.log('2번 문장 실행')
}, 3000)
console.log('3번 문장 실행')
}
timeout()
function run(callback, seconds){
if(!callback){
throw new Error('callback함수가 없습니다.')
}
if(!seconds || seconds<0){
throw new Error('초는 항상 0보다 커야합니다.')
}
setTimeout(callback, seconds)
}
run(() => {
console.log('타이머 완료')
}, 3000)
2. promise
function run(seconds){
return new Promise((resolve, reject) => {
if(!seconds || seconds < 0){
reject(new Error('초는 항상 0보다 커야함!'))
}
setTimeout(resolve, seconds)
})
}
run(-3000)
.then(() => console.log('타이머 완료!'))
.catch(console.error)
.finally(() => console.log('프로그램 종료!'))
3. promise-egg
function fetchEgg(chicken){
return Promise.resolve(`${chicken} => 🥚`)
}
function frtEgg(egg){
return Promise.resolve(`${egg} => 🍳`)
}
function getChicken() {
return Promise.resolve('🐔 => 🍗')
// return Promise.reject(new Error('치킨을 만들 수 없음'))
}
// getChicken()
// .catch(() => '🐔')
// .then(fetchEgg)
// .then (frtEgg)
// .then(console.log) // 리턴값 실행, finally없이도 실행
4. promise-all
function getBanana(){
return new Promise((resolve) => {
setTimeout(() => {
resolve('🍌')
}, 1000)
})
}
function getApple(){
return new Promise((resolve) => {
setTimeout(() => {
resolve('🍎')
}, 3000)
})
}
function getOrange() {
return Promise.reject(new Error('오렌지 없음!'))
}
getBanana()
.then((banana) => getApple().then((apple) => [banana, apple]))
.then(console.log)
// Promise.all : 병렬적으로 한 번에 Promise를 실행
Promise.all([getBanana(), getApple()]) // 동시 실행
.then((fruits) => console.log('all', fruits))
// Promise.race : 주어진 Promise중에 제일 빨리 수행된 것이 실행
Promise.race([getBanana(), getApple()])
.then((fruits) => console.log('race', fruits))
// Promise.all은 하나의 프로 미스라도 실패하면 전체를 에러로 처리함
Promise.all([getBanana(), getApple(), getOrange()]) // 동시 실행
.then((fruits) => console.log('all', fruits))
.catch(console.log)
//Promise.allSettled: 여러 프로미스를 병렬적으로 처리하되, 하나의 프로미스가 실해해도 무조건 이행
Promise.allSettled([getBanana(), getApple(), getOrange()])
.then((fruits) => console.log('all', fruits))
5. async
function getBanana(){
return new Promise((resolve) => {
setTimeout(() => {
resolve('🍌')
}, 1000)
})
}
function getApple(){
return new Promise((resolve) => {
setTimeout(() => {
resolve('🍎')
}, 3000)
})
}
function getOrange() {
return Promise.reject(new Error('오렌지 없음!'))
}
// getBanana()
// .then((banana) => getApple().then((apple) => [banana, apple]))
// .then(console.log)
async function fetchFruits() {
const banana = await getBanana()
const apple = await getApple()
return [banana, apple]
}
fetchFruits().then((fruits) => console.log(fruits))
6. async-all
function fetchEgg(chicken){
return Promise.resolve(`${chicken} => 🥚`)
}
function frtEgg(egg){
return Promise.resolve(`${egg} => 🍳`)
}
function getChicken() {
// return Promise.resolve('🐔 => 🍗')
return Promise.reject(new Error('치킨을 만들 수 없음'))
}
async function makeFriedEgg(){
let chicken
try {
chicken = await getChicken()
}catch{
chicken = '🐔'
}
const egg = await fetchEgg(chicken)
return fryEgg(egg);
}
makeFriedEgg().then(console.log)
7. json
const Rucy = {
name:'fnt1',
age:14,
eat() {
console.log('먹습니다.')
}
}
console.log(Rucy)
// 직렬화할 때 함수를 제외시키는 replacer 함수를 정의
const replacer = (key, value) => {
if(typeof value === 'function'){
return undefined
}
return value
}
const json =JSON.stringify(Rucy, replacer) // replacer를 전달
console.log(json)
const obj = JSON.parse(json)
console.log(obj)
8. fetch
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>fetch 테스트</title>
</head>
<body>
<h2>fetch 테스트</h2>
<script>
fetch('http://date.jsontest.com/')
.then((response) => {
return response.json()
})
. then((data) => console.log(data.date))
</script>
</body>
</html>
9. console
console.log('로딩중 ...')
console.clear() // 지우개
// 개발할 때 콘솔 사용법
console.log('log') // 개발
console.info('info') // 정보
console.warn('warn') // 경고
console.error('error') // 에어
// assert(조건을 만족하지 않으면 에러 메세지를 출력)
console.assert(2 === 2, '두 값이 달라요~') // 값이 출력되지 않음
console.assert(2 === 3, '두 값이 달라요~') // 값이 출력됨
// 객체 출력
const user = {userid:'apple', name:'김사과', age:20, company:{name:'SK', addr:'서울 중구'}}
console.log(user)
console.table(user)
console.dir(user, {showHidden:true, depth:0})
// trace 사용
function func1(){
func2()
}
function func2(){
func3()
}
function func3(){
console.log('func3() 실행!')
console.trace()
}
func3()
10. this
function hello(){
console.log(this) // global
console.log(this == global)
}
hello()
class ClassA {
constructor(num) {
this.num = num
}
classAMethod(){
console.log('-------------')
console.log(this) // 객체의 주소를 가리킴
console.log('-------------')
}
}
const classA = new ClassA(10)
classA.classAMethod()
console.log('----------')
console.log(this)
console.log(this == module.exports) // 모듈이다 -> import가능
11. module1
const counter = require('./counterone')
counter.increase()
counter.increase()
counter.increase()
console.log(counter.getCount())
let count = 0
function increase(){
count++
}
function getCount(){
return count
}
module.exports.getCount = getCount
module.exports.increase = increase
12. module2
{
"name": "day6",
"version": "1.0.0",
"description": "",
"main": "10_this.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
let count = 0
export function increase(){
count++
}
export function getCount(){
return count
}
// import { increase, getCount } from "./countertwo.js";
// increase()
// increase()
// increase()
// console.log(getCount())
import * as counter from './countertwo.js'
counter.increase()
counter.increase()
counter.increase()
console.log(counter.getCount())
13. path
const path = require('path')
// C:\HSH\KDT python\Web\JavaScript\Day6>
// POSIX(Unix, LInux, Mac): user/temp/Day6
console.log(__dirname) // 현재 디렉토리
console.log(__filename) // 현재 파일
console.log(path.sep)
console.log(path.delimiter)
console.log(path.basename(__filename)) // 파일 이름만 추출
console.log(path.basename(__filename, '.js')) // 확장자 제외
console.log(path.dirname(__filename)) // 해당 디렉토리만 추출
console.log(path.extname(__filename)) // 파일의 확장자만 추출
const parsed = path.parse(__filename)
console.log(parsed)
console.log(parsed.dir)
console.log(parsed.base)
const str = path.format(parsed)
console.log(str)
console.log('isAbsolute', path.isAbsolute(__dirname)) // 절대 경로
console.log('isAbsolute', path.isAbsolute('../Day6/')) // 상대 경로
14. file
const fs = require('fs')
// 동기식: 에러 처리를 꼭 해야함
// try{
// fs.renameSync('./test.txt', './new_test.txt')
// }catch(e){
// console.log(e)
// }
// console.log('정상적인 종료!!')
// 비동기식: 별도의 에러처리가 필요하지 않음
// fs.rename('./new_test.txt','./test.txt', (error) => {
// console.error(error)
// })
fs.promises
.rename('./test.txt','./new_test.txt')
.then(() => console.log('완료!!'))
.catch(console.error)
console.log('정상적인 종료!!')
'Node.js' 카테고리의 다른 글
2024년4월29일 Node.js-Refactoring (0) | 2024.05.01 |
---|---|
2024년 4월26일 Node.js-Express (0) | 2024.04.29 |
2024년 4월 25일 Node.js-post (1) | 2024.04.26 |
2024년 4워 24일 Node.js-Buffer (0) | 2024.04.24 |
2024년 4월 19일 Node.js (0) | 2024.04.21 |