Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
관리 메뉴

브이로그

2024년 4월 23일 Node.js-promise 본문

Node.js

2024년 4월 23일 Node.js-promise

황수환 2024. 4. 24. 02:54
더보기

콜백 지옥
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