2.ES6/Promise

2022. 9. 13. 12:40javascript

2022.09.13.화


1.ES6

1)spread

 -spread.js

/**
 * spread syntax 기호 : '...'
 * 하나로 뭉쳐있는 여러 값들의 집합을 펼쳐서(전개, 분산) 개별적인 값들의 목록으로 바꿈
 * 
 * spread 문법 사용 가능 대상 : array, String, Map, Set, DomCollection 등으로 한정
 */

//1.Spread With Arrays
const fruits = ['apple', 'banana'];
const otherFruits = ['kiwi', 'podo'];

//기본의 배열 연결(concatenation) 방식
const allFruits = fruits.concat(otherFruits);

//spread 활용 방식
const myFruits = [...fruits, ...otherFruits, 'pear'];

//users array에 새로운 user 객체를 추가하려면?
const users = [
    {id: 1, userName: 'Coo'},
    {id: 2, userName: 'kie'},
]

//기존의 방식
const newUser = {id: 3, userName: 'Run'};
users.push(newUser);

//spread 방식
const secondNewUser = {id: 4, userName: 'zzang'};
const updatedUsers = [...users, secondNewUser];

//spread 연산을 해도 원본 배열은 변하지 않음

//배열의 복사
const originalArray = ['one', 'two', 'three'];
const secondArray = originalArray;

secondArray.pop(); //secondArray의 가장 뒤에 있는 요소 제거했는데
console.log(originalArray); //원본이 변함, 같은 참조값을 참조하고 있기 때문

const originalArrayWithSpread = ['four', 'five', 'six'];
const secondArrayWithSpread = [...originalArrayWithSpread];
secondArrayWithSpread.pop(); //second pop해도,
console.log(originalArrayWithSpread); //원본은 변경되지 않음

//2.문자열도 가능
const aString = 'hello';
const strArray = [...aString];
console.log(strArray); //['h', 'e', 'l', 'l', 'o']

//3.Spread with object : spread를 통해 겍체를 복사하거나 수정할 수 있음

// 기존의 방식을 사용한 object shallow copy
// const originalObject = { enabled: true, darkMode: false}
// const secondObject = Object.assign({}, originalObject);
// secondObject.enabled = false
// console.log(secondObject.enabled);
// console.log(originalObject.enabled); // 원본은 바뀌지 않음.
// console.log(originalObject === secondObject); // 참조값 비교

//spread를 활용한 object shallow copy
const originalObject = { enabled: true, darkMode: false }
const secondObject = { ...originalObject };
secondObject.enabled = false;
console.log(originalObject.enabled);

//spread를 활용한 프로퍼티의 추가
const user = {
    id: 3,
    name: 'john',
};

//user 객체에 isLoggedIn 프로퍼티를 추가하려고 하는데, 새로운 객체에만 적용하고 싶을 때
const updatedUser = {...user, isLoggedIn: true};
console.log(updatedUser);

//spread를 활용한 프로퍼티의 수정
//user객체에 있는 name 프로퍼티의 값을 'mary'로 수정해서 새로운 객체로 생성
const updatedUserName = {...user, name: 'mary'};

 -spread.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="spread.js"></script>
    <title>Javascript spread syntax(Javascript 전개 문법)</title>
</head>
<body>
    <h1>Javascript spread syntax(Javascript 전개 문법)</h1>
    <hr>
    

</body>
</html>

2)destructuring

 -destructuring.js

/**
 *  Destructing Assignment('분해'해서 '할당')
 * 객체의 프로퍼티나 배열의 요소들을 변수로 분해주는 것을 뜻함
 * 코드를 더 간결하게 도와주는 기능
 * 
 * 1.Object Destructuring
 * 2.Array Destructuring
 */

//1.Object Destructuring
const book = {
    id: 1,
    title: 'The great Gatsby',
    pubDate: '10/04/1925',
}

//기존 방식
// const id = book.id;
// const title = book.title; //..

//in react, import { useState } from 'react'
// const { id, title, pubDate } = book;

//중첩 객체 destructuring 기능
const anotherBook = {
    id: 2,
    title:  'Story of Your Life',
    pubDate: '08/08/1998',
    author: {
        firstName: 'Chang',
        lastName: 'Ted',
    }
}

const {id, title, pubDate, author: { firstName, lastName } } = anotherBook;

 -destructuring.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="destructuring.js"></script>
    <title>Javascript Destructuring(Javascript 구조분해할당)</title>
</head>
<body>
    <h1>Javascript Destructuring(Javascript 구조분해할당)</h1>
    <hr>
</body>
</html>

2.Promise

 -callback_hell.js

/**
 * JS에서는 비동기 처리를 위한 하나의 패턴으로 콜백 함수 패턴을 사용함
 */

//전통적인 콜백 패턴
// const xhr = new XMLHttpRequest();

// xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1');
// xhr.send();

// xhr.onload = () => {
//     if(xhr.status === 200) {
//         console.log(xhr.response);
//     }
// };

//Callback hell ? 어떠한 비동기 요청에 대한 처리 결과로 얻은 하나의 값
//또 다른 비동기 요청을 하고자 할 때 발생할 수 있는 가독성 저하 케이스
const get = (url, callbackFn) => {
    const xhr = new XMLHttpRequest();

    xhr.open('GET', url);
    xhr.send();

    xhr.onload = () => {
        if(xhr.status === 200) {
            callbackFn(JSON.parse(xhr.response));
        }
    }
};

console.log(get);

const url = 'https://jsonplaceholder.typicode.com';

//id가 1인 post의 userId 취득
get(`${url}/posts/1`, (userId) => {
    console.log(userId);

    //post의 userId의 id를 활용하여 user의 정보 취득
    get(`${url}/users/${userId.id}`, userInfo => {
        console.log(userInfo);
    })
});

 -promise.js

/**
 * 기존의 XMLHTTP 방식으로는 콜백 헬, 예외처리 등이 곤란함
 * 그 대처방안으로 등장한 것이 ES6에서 나온 Promise
 * 
 * callback_hell.js에서 본 것처럼 콜백 헬, 예외 처리 등을 해결하기 위해 사용
 */

//비동기 요청의 성공 여부 isSuccess
const isSuccess = true; //요청이 성공했다고 가정

const promise = new Promise((resolve, reject) => {
    //promise 생성자 함수(메서드)의 콜백 함수 내부에서 비동기 처리 수행
    //promise 생성자 함수 ? -> new Promise()

    //비동기 처리가 성공하면 콜백 함수의 인수로 전달받은 resolve()가 호출됨
    //비동기 처리가 실패하면 reject()가 호출됨

    if(isSuccess) {
        resolve('비동기 처리에 따른 응답 결과 값 작성 부분');
    }
    else {
        reject('비동기 처리실패에 따른 예외처리 작성 부분');
    }
});
// console.log(promise);
//PromiseState(비동기 처리 상태 정보)
//PromiseResult(비동기 처리 결과 정보, 서버로부터 응답받은 결과값)

/**
 * 비동기 처리의 3가지 진행 상태
 * pending : 비동기 처리가 아직 수행되지 않은 상태
 * fulfilled : 비동기 처리가 수행된 상태(성공)
 * rejected : 비동기 처리가 수행된 상태(실패)
 * 
 * new Promise(callback)를 통해 생성한 직후 pending 상태
 * 이후 비동기 처리가 수행되면, 비동기 처리 결과에 따라 promise 객체의 state가 변경됨
 * 
 * 처리가 성공했다 ? resolve() 호출, Promise 객체의 상태를 fulfilled 상태로 변경
 * 처리가 실패했다 ? reject() 호출, Promise 객체의 상태를 rejected 상태로 변경
 * 
 * 정리하면, promise는 비동기 처리 상태와 처리된 응답 결과를 관리하는 객체
 */

//promise를 활용한 비동기 요청
const getRequestWithPromise = url => {
    return new Promise((resolve, reject) => {
        //비동기 요청 진행
        const xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        xhr.send();

        xhr.onload = () => {
            if(xhr.status === 200) {
                //응답 성공
                resolve(JSON.parse(xhr.response));
            }
            else {
                //응답 실패
                reject(new Error(xhr.status));
            }
        }
    })
}
console.log(getRequestWithPromise('https://jsonplaceholder.typicode.com/posts/1'));

 -after_promise.js

/**
 * Promise 비동기 처리상태(pending, fulfilled, rejected)의 변화에 따라
 * 후속 처리를 진행
 * 
 * fulfilled 상태면 처리 결과(응답 데이터)를 가지고 무언가를 해야하고,
 * rejected 상태면 에러 처리를 함
 * 
 * 이러한 후속 처리를 위해 then(), catch(), finally() 등의 메서드를 제공함
 * -> 후속 처리 메서드라고 함
 * 모든 후속 처리 메서드들은 다시 Promise 객체를 반환
 */

//fulfilled
new Promise(resolve => resolve('fulfilled 상태')).then(result => console.log(result));

//rejected
new Promise((_, reject) => reject(new Error('rejected')))
.then(result => console.log(result), error => console.error(error));

//catch()는 실패했을 때 활용
new Promise((_, reject) => reject(new Error('rejected')))
.catch(error => console.error(error));

const getRequestWithPromise = url => {
    return new Promise((resolve, reject) => {
        //비동기 요청 진행
        const xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        xhr.send();

        xhr.onload = () => {
            if(xhr.status === 200) {
                //응답 성공
                resolve(JSON.parse(xhr.response));
            }
            else {
                //응답 실패
                reject(new Error(xhr.status));
            }
        }
    })
}

getRequestWithPromise('https://jsonplaceholder.typicode.com/posts/1')
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(() => console.log('요청 종료'));

 -fetch.js

/**
 * fetch
 * XMLHTTPRequest처럼 HTTP 요청 전송 기능을 지원하는 Web API
 * 사용법이 간편하고, 프로미스를 지원
 * fetch()의 반환 타입은 promise 객체
 * 
 * proto-type
 * fetch(url, [options])
 * 
 * fetch()는 HTTP 응답을 나타내는 response 객체를 감싼(Wrapping) promise 객체를 반환함
 * fetch()의 첫번째 인수로 HTTP 요청을 전송할 URL만 전달하면, 기본 요청은 GET방식
 */

const url = 'https://jsonplaceholder.typicode.com/posts/1';

const promise = fetch(url).then(response => console.log(response));
// console.log(promise);

const promise2 = fetch(url).then(response => response.json()) //Response 객체가 제공하는 메서드 json()
//Response.json() : fetch()가 반환한 프로미스가 감싸고 있는 응답 데이터 중에서 body를 취득하기 위해 사용하는 메서드
//-> Response 객체에서 HTTP 응답 몸체(response.body)를 취득(JSON.parse())
.then(json => console.log(json));

//axios

 -index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- <script src="callback_hell.js"></script> -->
    <!-- <script src="promise.js"></script> -->
    <!-- <script src="after_promise.js"></script> -->
    <script src="fetch.js"></script>
</head>
<body>
    
</body>
</html>

'javascript' 카테고리의 다른 글

1.동기, 비동기/ajax/json/node.js  (1) 2022.08.22
0.javascript 문법  (0) 2022.08.18