2carrot84
by 2carrot84
4 min read

Categories

  • lecture

Tags

  • ECMA Script
  • Node.js
  • const
  • let
  • modern javascript

이번 수업에 들은 ‘모던 자바스크립트 살펴보기’에 대한 내용입니다.

이런 정보를 찾아보며 개발을 한다는 사실이 저에겐 흥미로웠습니다.

모던 자바스크립트 살펴보기

TC39

ECMA Script (= javascript) 의 표준을 재정 하고 update를 관리하는 조직

node.green

Node 버전별 구현된 기능을 확인할 수 있는 페이지
위 ECMA Script 표준 및 Update 진행 중인 기능 들이 어디까지 구현되어 있는지 확인할 수 있음

let, const - ES2015 오픈

hoisting 규칙이 없고, block scoping (block 내 선언된 변수는 block 내에서만 사용) 을 지원함

  • let 은 레퍼런스(값이)가 바뀔 수 있고, const 는 바뀔 수 없다 (= final)
  • var 와 달리 let 과 const 는 같은 스코프내 같은 변수를 두번 이상 선언할 수 없다. (Syntax Error)
  • let 과 const 의 예측 가능성ㅇ과 유지보수성이 var 보다 훨씬 뛰어남

가능하면 const 만 사용하고, 필요시 let 은 사용하나, var 는 절대 사용 하지 마라

let x = 1
x = 2 // Ok

const y = 1
y = 2 // TypeError
var x = 1
var x = 2 // OK

let x = 1
let x = 2  // SyntaxError
console.log(x)  // OK
var x = 0

console.log(x) // Error
const x = 0
var x = 1
{
    var x = 2
    console.log(x)  // 2
}
console.log(x)  // 2

const x = 1
{
    const x = 2
    console.log(x)  // 2
}
console.log(x)  // 1

Spread Syntax - ES2015 오픈

// object merge (1)
const personalData = {
    nickname: 'CG',
    email: '2carrot84@gmail.com',
}

const publicData = {
    age: 22,
}

const user = {
    ...personalData,
    ...publicData,
}

console.log(user)   //  { nickname: 'CG', email: '2carrot84@gmail.com', age: 22 }
// object merge (2)
const overrides = {
    DATABASE_HOST: 'myhost.com',
    DATABASE_PASSWORD: 'mypassword',
}
const config = {
    DATABASE_HOST: 'default.host.com',
    DATABASE_PASSWORD: '****',
    DATABASE_USERNAME: 'myuser',
    ...overrides
}
/*{
    DATABASE_HOST: 'myhost.com',
    DATABASE_PASSWORD: 'mypassword',
    DATABASE_USERNAME: 'myuser',
}*/
// object rest
const user = {
    nickname: 'CH',
    age: 22,
    email: '2carrot84@gmail.com'
}

const { nickname, ...personalData } = user  // nickname 제외 후 personalData 객체 생성
console.log(personalData)   //  { age: 22, email: '2carrot84@gmail.com' }
// array merge
const pets = ['dog', 'cat']
const predators = ['wolf', 'cougar']
const animals = [...pets, ...predators]

console.log(animals)    // [ 'dog', 'cat', 'wolf', 'cougar' ]
function foo(head, ...rest) {
    console.log(head)
    console.log(rest)
}
foo(1, 2, 3, 4)
/*
1
[ 2, 3, 4 ]
 */

Promise

비동기 작업 종료 시점의 완료 or 실패와 그 결과 값을 나타냄
미래의 어떤 시점에 결과를 제공하겠다는 약속(Promise)를 반환

Promise 상태

  • pending (대기) : 이행하지도, 거부하지도 않은 초기 상태
  • fulfuilled (이행) : 연산이 성공적으로 완료
  • reject (거절) : 연산 실패

resolve()

주어진 값으로 이행하는 Promise 객체를 반환
지정한 값이 then 메서드를 가지는 경우, Promise.resolve() 가 반환하는 Promise는 then 메서드를 따라가서 자신의 최종 상태를 결정

reject(reason)

주어진 사유로 거부하는 Promise 객체를 반환

then

Promise 에 이행과 거부처리기 콜백을 추가

catch

Promise 에 거부처리기에 콜백을 추가

finally

Promise 에 이행, 거부에 상관 없이 항상 호출

const sleep = (ms) => {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    })
}

new Promise((resolve, rejects) => {
    console.log('Inside promise')
    sleep(1000)
    rejects(new Error('First reject'))
    resolve('First resolve')
}).then(value => {
    console.log('Inside first then')
    console.log('value', value)
}).catch(error => {
    console.log('error', error)
})
/*
Inside promise
error
:Error: First reject
 */

new Promise((resolve, rejects) => {
    console.log('Inside promise')
    rejects(new Error('First reject'))
    resolve('First resolve')
}).catch(error => {
    console.log('error', error)
}).then(value => {
    console.log('Inside first then')
    console.log('value ', value)
})
/*
Inside promise
error
:Error: First reject
Inside first then
value undefined
 */

new Promise((resolve, rejects) => {
    console.log('Inside promise')
    setTimeout(() => {
        resolve(Math.random())
        console.log('After resolve')
    }, 1000)
}).then((value) => {
    console.log('then 1')
    console.log('value :', value)
}).then((value) => {
    console.log('then 2')
}).then((value) => {
    console.log('then 3')
})
/*
Inside promise
After resolve
then 1
value0.6893501856716817
then 2
then 3
 */
function returnPromiseForTimeout() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(Math.random())
        }, 1000)
    })
}

returnPromiseForTimeout()
    .then(value => {
        console.log(value)
        return returnPromiseForTimeout()
    })
    .then(value => {
        console.log(value)
        return returnPromiseForTimeout()
    })
    .then(value => {
        console.log(value)
        return returnPromiseForTimeout()
    })
    .then(value => {
        console.log(value)
        return returnPromiseForTimeout()
    })
/*
0.8451924276841662
0.3173270175130023
0.2899827674825355
0.8148152584175137
 */

setTimeout(() => {
    const value1 = Math.random()
    console.log(value1)
    setTimeout(() => {
        const value2 = Math.random()
        console.log(value2)
        setTimeout(() => {
            const value3 = Math.random()
            console.log(value3)
            setTimeout(() => {
                const value4 = Math.random()
                console.log(value4)
            }, 1000)
        }, 1000)
    }, 1000)
}, 1000)

/*
0.8581614552504644
0.3946617212828898
0.8469318628343485
0.7590294478424375
 */
const fs = require('fs')
async function main() {
    try {
        const result = await fs.promises.readFile('../.gitignore', 'utf-8')
        console.log(result)
    } catch (e) {
        console.log('error', e)
    }
}
main()

function readFileInPromise(filename) {
    return new Promise((resolve, reject) => {
        fs.readFile(filename, 'utf-8', (error, value) => {
            if (error) {
                reject(error)
            }
            resolve(value)
        })
    })
}

readFileInPromise('.gitignore').then(value => console.log(value))

fs.readFile('.gitignore', 'utf-8', (error, value) => {
    console.log(value)
})
fs.promises.readFile('../.gitignore', 'utf-8')
    .then(value => console.log(value))

async / await

async

비동기 함수를 async 함수로 만들기 위하여 function() 앞에 async 키워드 추가
async 함수는 await 키워드가 비동기ㅣ 코드를 호출할 수 있게 해주는 함수
async 키워드 추가 시 함수는 결과 대신 Promise 를 반환

await

await + async 함수 사용시 장점이 확실
Promise 기반 함수 앞에 놓을 수 있음

  • Promise 가 fulfil 될때까지 잠시 중단하고 결과를 반환
  • 실행을 기다리는 다른 코드들을 중지 없이 실행
async function sleep(duration) {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(undefined)
        }, duration)
    })
}

async function main() {
    console.log('first')
    await sleep(1000)
    console.log('second')
    await sleep(1000)
    console.log('third')
    await sleep(1000)
    console.log('finish!')
}

main()
/*
first
second
third
finish!
 */

마무리

기록을 하고 있지만 돌아서면 까먹는건 집중을 못한 탓일까.. 나이 탓일까.. 🤔😂

그럼 이만. 🥕👋🏼🖐🏼