문득 든 의문점

[JS] cachingdecorator 에서 어떻게 Map으로 저장한 데이터가 유지될까?

OnnJE 2022. 12. 15. 17:08
반응형

Caching Decorator

function slow(x) {
  // CPU 집약적인 작업이 여기에 올 수 있습니다.
  alert(`slow(${x})을/를 호출함`);
  return x;
}

function cachingDecorator(func) {
  let cache = new Map();

  return function(x) {
    if (cache.has(x)) {    // cache에 해당 키가 있으면
      return cache.get(x); // 대응하는 값을 cache에서 읽어옵니다.
    }

    let result = func(x);  // 그렇지 않은 경우엔 func를 호출하고,

    cache.set(x, result);  // 그 결과를 캐싱(저장)합니다.
    return result;
  };
}

slow = cachingDecorator(slow);

alert( slow(1) ); // slow(1)이 저장되었습니다.
alert( "다시 호출: " + slow(1) ); // 동일한 결과

alert( slow(2) ); // slow(2)가 저장되었습니다.
alert( "다시 호출: " + slow(2) ); // 윗줄과 동일한 결과

  위 코드는 javscript.info 사이트에서 가져온 cachinDecorator의 예제이다.  위 코드에서 cachingDecorator는 function(x)을 반환한다 function(x)은 cache에 x의 결과값이 저장되어있으면 해당 결과값을 바로 반환하고 그 외의 경우 cachingDecorator가 받은 func함수에 인자로 넘긴 결과값을 반환한다.

 

클로저

  클로저는 outer 함수의 변수나 파라메터에 접근하는 함수이다. 예를 들면 클로저에서 외부 함수의 i라는 변수에 접근한다고 가정해보자, 만약 i가 constant라면 큰 문제가 되지 않을 것이다. 하지만 만약 i가 변수이고 우리의 의도가 i가 변하는 것을 이용해 결과를 내는 것이라면 이 부분에서 문제가 발생할 수 있다. 아래 코드를 보자

 

let arr = []

for (let i = 0; i < 10; i++) {
	arr[i] = function(i) {
    	return i * 10
    }
}

console.log(arr[1]()) //100

 

 

 만약 위 코드를 통해 [10, 20, 30, ..., 100]의 arr에 저장된 함수가 반환하기를 기대하고 작성했다면, 코드가 의도와는 다르게 동작함을 깨달을 것이다. 이는 앞서 말했듯이 arr에 저장된 함수는 outer 함수의 변수인 i를 참조하고 있으며 arr[1]() 호출되었을 때엔 i는 이미 루프를 모두 돌고 10이 됐기 때문이다. 이를 해결하기 위해 즉시실행 함수를 사용하기도 하는데 거기까진 설명하지 않겠다.

 

정리

  다시 돌아와서, cachingdecorator 에서 어떻게 Map으로 저장한 데이터가 유지될까? 그 이유는 우리가 slow에 cashingDecorator함수의 리턴값을 저장했기 때문이다. 즉 slow는 아래 코드로 변경되었으며, 클로저로서 기능한다.

 

function(x) {
    if (cache.has(x)) {    // if there's such key in cache
      return cache.get(x); // read the result from it
    }

    let result = func(x);  // otherwise call func

    cache.set(x, result);  // and cache (remember) the result
    return result;
  };

 

 

이 코드는 cachingDecorator의 cache 변수를 참조하고 조건에 따라 데이터를 불러오거나 추가한다. 즉, cache는 클로저 예시코드의 i 처럼 동작한다. 클로저가 호출될때 조건에 따라 업데이트되고 가비지 컬렉션에 의해 지워지지 않는이상 유지되는 것이다.

반응형