불변 객체

자바스크립트에서 객체의 상태(즉, 프로퍼티의 값)가 생성 후 변경될 수 없는 객체를 의미

객체의 불변성을 유지한다는 것

 

사용하는 경우

  • 객체에 변화를 가해도 원본이 그대로 남아있어야 하는 경우
  • 특히, 메모리(데이터베이스)에 저장 되어 있는 객체를 다루는 경우
  • 불변객체를 이용하여 상태변화를 추적해야하는 경우

사용하는 이유

  • 오류감소 : 객체의 상태가 변경되지 않기 때문에 예기치 않은 상태 변경으로 인한 버그감소
  • 성능최적화 : 복제나 비교를 위한 조작을 단순화 할 수 있고 성능 개선에도 도움

불변객체를 만드는 방법

Object.freeze() [ ref ]

const user= {
   name: "JJ",
   age : 38,
   address : {
     nation: "Korea",
     city: "JinJu"
   }
}

Object.freeze(user) // 상위레벨에 있는 것만 보호

user.name = "KK"
user.address.city = "Seoul"

console.log(user.name) // "JJ"
console.log(user.address.city) // "Seoul"


// deep freeze
const deepFreeze = obj => {
  Object.keys(obj).forEach(prop => {
    if (typeof obj[prop] === 'object') deepFreeze(obj[prop]);
  });
  return Object.freeze(obj);
};

 

Spread 연산자 [ ref ]

- 새로운 객체를 만들 때 사용

const obj1 = { type: 'data' }
const arr1 = [1, 2, 3]

const obj2 = { ...obj1, subtype: 'stuff' } // 원본 유지하면서 새로운 프로퍼티 추가
const arr2 = [ ...arr1, 'cheese' ] // 새로운 요소 추가


const data = { type: 'data', age: 55 }
const data2 = { ...obj1, age: obj1.age + 1 }// 원본 유지하면서 기존의 데이터 변경

 

 

꼭 변환을 해야한다면 깊은 복사를 하여  복사본을 변경을 하는 것을 추천한다.

// 스프레드 연산자

const originalArray = [ 1,2, 3]
const deepCopyArray = [ ... originalArray]

const user= {
   name: "JJ",
   age : 38,
   address : {
     nation: "Korea",
     city: "JinJu"
   }
}

// 1 단으로만 이루어진 객체에서는 가능
// spread
const copyUser = { ...user}
copyUser.name = "N"
copyUser.address.city = "Seoul"

// 원본 user 가 변경되었는지 확인
console.log(user.name) // "JJ" : 변경 안됨
console.log(user.address.city) // "Seoul" : "JinJu" 에서 "Seoul" 로 변경

// Object.assign 도 동일
const copyUserObjectAssign = Object.assign({}, user);


/* 1단 이상인 경우 */

// JSON 이용
const userCopyJSON = JSON.parse(JSON.stringify(user));


// 재귀함수 이용
function CopyObjectDeeply(target) {
  var result = {};

  if (typeof target === "object" && target !== null) {
    for (var prop in target) {
      result[prop] = copyObjectDeep(target[prop]); // 재귀적 호출
    }
  } else {
    result = target;
  }

  return result;
};

const userCopyFunction = CopyObjectDeeply(user)

 

 

참고자료

https://velog.io/@jujusnake/JavaScript-%EB%B6%88%EB%B3%80-%EA%B0%9D%EC%B2%B4-immutable-objec#%EA%B9%8A%EC%9D%80-%EB%B3%B5%EC%82%AC

 

[JavaScript] 불변 객체 immutable objec

참조형 데이터가 완전히 불변성을 띄도록 만들 수는 없을까?

velog.io

https://velog.io/@gusdh2/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8JavaScript-%EA%B0%9D%EC%B2%B4%EC%99%80-%EB%B6%88%EB%B3%80%EC%84%B1#%EB%B6%88%EB%B3%80%EC%84%B1%EC%9D%B4%EB%9E%80

 

자바스크립트(JavaScript) 객체와 불변성

불변성(Immutability)은 객체가 생성된 이후 그 상태를 변경할 수 없는 것을 의미합니다. 불변성은 함수형 프로그래밍의 핵심 원리이다.불변 객체를 사용하면 복제나 비교를 위한 조작을 단순화 할

velog.io

 

 

https://developer.mozilla.org/ko/docs/Glossary/Deep_copy

 

깊은 복사 - MDN Web Docs 용어 사전: 웹 용어 정의 | MDN

객체의 깊은 복사는 복사본의 속성이 복사본이 만들어진 원본 객체와 같은 참조(메모리 내의 같은 값을 가리킴)를 공유하지 않는 복사입니다. 따라서 원본이나 복사본을 변경할 때, 다른 객체가

developer.mozilla.org

https://www.freecodecamp.org/news/immutable-javascript-improve-application-performance/

 

Immutable JavaScript – How to Improve the Performance of Your JS Applications

Javascript has become a very popular programming language thanks to its growing use in frontend and backend development. And as devs build JavaScript applications for different companies and organizations, the size and complexity of these applications can

www.freecodecamp.org

https://www.freecodecamp.org/news/javascript-immutability-frozen-objects-with-examples/

 

JavaScript Immutability – Frozen Objects in JS Explained with Examples

In JavaScript, we use an Object to store multiple values as a complex data structure. You create an object with a pair of curly braces {}. An object can have one or more properties. Each of the properties is a key-value pair separated by a colon(:). The ke

www.freecodecamp.org

https://dev.to/glebec/four-ways-to-immutability-in-javascript-3b3l

 

Four Ways to Immutability in JavaScript

An interactive look at four persistent data techniques

dev.to

 

'프로그래밍 > JavaScript' 카테고리의 다른 글

[ JS ] Promise.allSettled 사용하는 이유  (0) 2024.05.06
[ JS ] Promise.all() 사용하는 이유  (0) 2024.05.06
[ JS ] Promise 설명  (0) 2024.05.05
[ JS ] 정렬 sort( )  (0) 2024.04.13
[JS] call, apply, bind  (0) 2024.03.06

 

Promise.all() 은 요청한 것이 모두 성공해야 값을 반환하므로 요청한 모든 값이 필요할 때 사용을 하면 좋다.

 

Promise.allSettled() 은 요청이 성공하던 실패를 하던 모든 값을 반환해준다.

 

코드예시

const urls = [
  'https://api.github.com/users/iliakan',
  'https://api.github.com/users/Violet-Bora-Lee',
  'https://no-such-url'
];

Promise.allSettled(urls.map(url => fetch(url)))
  .then(results => { // (*)
    results.forEach((result, num) => {
      if (result.status == "fulfilled") {
        alert(`${urls[num]}: ${result.value.status}`);
      }
      if (result.status == "rejected") {
        alert(`${urls[num]}: ${result.reason}`);
      }
    });
  });

 

결과

[
  {status: 'fulfilled', value: ...응답...},
  {status: 'fulfilled', value: ...응답...},
  {status: 'rejected', reason: ...에러 객체...}
]

 

스펙에 추가된 지 얼마 안 된 문법이라 지원이 안되면 구현해야한다고 한다.

//https://ko.javascript.info/promise-api#ref-1314
if(!Promise.allSettled) {
  Promise.allSettled = function(promises) {
    return Promise.all(promises.map(p => Promise.resolve(p).then(value => ({
      status: 'fulfilled',
      value
    }), reason => ({
      status: 'rejected',
      reason
    }))));
  };
}

 

 

사용하는 이유 및 상황

 

모든 값이 무조건 다 필요하지 않는 경우.

실패한 경우에 다르게 처리를 해줄 필요가 있는 경우.

    (예시) 한 해쉬태그가 있는지 조회를 했을 때 없는경우 -> 해당 해쉬태그를 등록

 

 

 

참고자료

https://ko.javascript.info/promise-api#ref-1314

 

프라미스 API

 

ko.javascript.info

 

'프로그래밍 > JavaScript' 카테고리의 다른 글

[ JS ] 불변객체 immutable object  (0) 2024.05.11
[ JS ] Promise.all() 사용하는 이유  (0) 2024.05.06
[ JS ] Promise 설명  (0) 2024.05.05
[ JS ] 정렬 sort( )  (0) 2024.04.13
[JS] call, apply, bind  (0) 2024.03.06

all 안에 주어진 배열에 있는 모든 프로미스를 실행한 후에  그 결과를 배열에 있는 순서대로 반환

배열에 있는 요청 중 하나라도 reject 가 되면  다른 요청의 성공여부에 상관없이 전부 reject

 

코드 예시

//Promise.all( 순회가능한 객체/ 배열 ) 
const promise1 = Promise.resolve("Test Promise.all()");
const promise2 = 5;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
  
// Array ["Test Promise.all()", 5, "foo"]

 

await 를 3개를 사용한 것과 같은 결과를 보여주지만,

좀 더 복잡한 코드를 수행해야할 때는 Promise.all([promise1, ... ]) 이 더 빠르다.

 

사용하는 이유 및 상황

처리속도

만약에 await 를 이용하여 3개의 요청을 실행을 하면 각 요청이 순서대로 실행이된다.

 

하지만, Promise.all()을 이용하여 요청들을 실행하면

Promise.all() 안에 있는 요청들만  병렬로 실행되고 이 요청이 완성될때까지 다른 요청들은 실행 되지 않는다.

이로 인해 요청들을 수행하는데 소요되는 시간이 더 짧아지고 결과를 한꺼번에 처리 가능하다.

-  필요한 요소들을 한꺼번에 처리할 때 유리하다.

 

(사용되는 예시)

게시물을 생성할 때 -> hashtag 정보 검색/ 생성, 카테고리 정보 검색, 새로운 게시물 데이터 생성 필요

-> 3가지를 Promise.all() 을 이용하여 한번에 실행하고 그 결과들을 수집및 처리하여 db에 저장 

 

배열 속의 모든 프로미스의 결과가 필요한 경우

 

'프로그래밍 > JavaScript' 카테고리의 다른 글

[ JS ] 불변객체 immutable object  (0) 2024.05.11
[ JS ] Promise.allSettled 사용하는 이유  (0) 2024.05.06
[ JS ] Promise 설명  (0) 2024.05.05
[ JS ] 정렬 sort( )  (0) 2024.04.13
[JS] call, apply, bind  (0) 2024.03.06

Promise 란?

프로미스가 생성된 시점에는 알려지지 않았을 수도 있는 값을 위한 대리자로, 비동기 연산이 종료된 이후에 결과 값과 실패 사유를 처리하기 위한 처리기를 연결할 수 있습니다. 프로미스를 사용하면 비동기 메서드에서 마치 동기 메서드처럼 값을 반환할 수 있습니다. 다만 최종 결과를 반환하는 것이 아니고, 미래의 어떤 시점에 결과를 제공하겠다는 '프로미스(promise)'를 반환합니다.

 

쉽게 말해서 비동기 작업이 필요할 때 사용되는 객체

  • 비동기 작업
    • 특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드를 먼저 수행하는 자바스크립트의 특성
    • 비동기 작업은 주로 I/O 작업이나 네트워크 요청과 같이 시간이 오래 걸리는 작업에 유용
    • 콜백, aync/ await 의 매커니즘으로도 구현 가능

Promise 는 비동기 작업의 최종 완료 결과 또는 실패 만을 반환

let promise = new Promise(function(resolve, reject) {
  // executor (코드)
});

let promise2 = new Promise((resolve, reject) => {
  // executor (코드)
});

 

위의 예시 코드에 보이듯이 Promise 는  resolve 와 reject를 반환

  • resolve(status: fullfilled, result: value) — 일이 성공적으로 끝난 경우 그 결과를 나타내는 value와 함께 호출
  • reject(status: rejected, result: error) — 에러 발생 시 에러 객체를 나타내는 error와 함께 호출

반환된 결과를 사용하기 위한 메서드

.then()   

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(3);
  }, 300);
});

myPromise
  .then((value) => value *3) // 9
  .then((value) => value *3) // 27
  .then((value) => {
    console.log(value);
  })
 // 27

 

.catch()   .finally() 

let myPromise = new Promise(function(resolve, reject) {
  setTimeout(() => reject(new Error("error!"));
});

myPromise
 .then((result) => console.log(result);)
 .catch((error) => console.log(error);)
 .finally(() => console.log("Done"););
 // error!
 // Done

 

 

단순한 예시

const promiseA = new Promise((resolve, reject) => {
  resolve(1);
});

promiseA.then((val) => console.log("출력 순서 테스트:", val));
console.log("출력 순서 테스트: 2");

// 아래 순서로 출력이 실행

// 출력 순서 테스트 : 2
// 출력 순서 테스트 : 1

 

비동기 데이터 요청

function getData(url) {
  return new Promise((resolve, reject) => {
    fetch(url)
      .then(response => {
        if (response.ok) // 요청이 성공 
        {
          return response.json();
        } 
        else { 
          throw new Error('Something went wrong');
        }
      })
      .then(data => resolve(data))
      .catch(error => reject(error));
  });
}

getData('https://www.example.com/data')
  .then(data => console.log(data))
  .catch(error => console.error(error));
  
  
// fetch 의 기본적인 구조 요청 예시
fetch('https://jsonplaceholder.typicode.com/posts/1')
  .then((response) => response.json()) // 응답 객체에서 JSON 데이터를 추출한다.
  .then((data) => console.log(data)); // JSON 데이터를 콘솔에 출력한다.

참고자료

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise

 

Promise - JavaScript | MDN

Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.

developer.mozilla.org

https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Using_promises

 

Using promises - JavaScript | MDN

Promise는 비동기 작업의 최종 완료 또는 실패를 나타내는 객체입니다. 대부분 여러분은 이미 만들어진 promise를 사용했었기 때문에 이 가이드에서는 어떻게 promise를 만드는지 설명하기에 앞서 prom

developer.mozilla.org

https://ko.javascript.info/promise-basics

 

프라미스

 

ko.javascript.info

 

'프로그래밍 > JavaScript' 카테고리의 다른 글

[ JS ] Promise.allSettled 사용하는 이유  (0) 2024.05.06
[ JS ] Promise.all() 사용하는 이유  (0) 2024.05.06
[ JS ] 정렬 sort( )  (0) 2024.04.13
[JS] call, apply, bind  (0) 2024.03.06
객체(Object), 객체 메소드  (0) 2023.08.03

+ Recent posts