카카오맵에 이벤트가 1개만 등록되게 하는 방법이 있을까요?

[FAQ] 지도/로컬 API 문의 전 꼭 읽어 주세요.
https://devtalk.kakao.com/t/faq-api/125610

카카오맵에 클릭 이벤트로 함수 1개를 2번 등록했습니다
아이디가 다른 2개의 컨트롤러에서 각각 이벤트를 등록했는데요
지도에 있는 이벤트를 콘솔에 찍어보면 같은 배열을 사용하고 있는 것으로 보입니다
컨트롤러 하나를 클릭하고 원을 그리지 않는다 → 다른 컨트롤러를 클릭하고 원을 그린다 → 원이 2번 그려진다

이 상태에서 두번째 클릭 후 원을 하나만 그릴 수 있게 만들 수 있을까요?

// 컨트롤러
  let circleArray = [];

  const setDestinationFunc = (e) => {
    e.stopPropagation();
    var OnceD = document.getElementsByClassName("once-D");
    if (OnceD[0]) {
      console.log(OnceD[0], setDestinationBtn);
    }
    setDestinationBtn.disabled = true;
    setPathBtn.disabled = true;
    deleteDestination.disabled = true;
    if (setDestinationBtn.classList.contains("once-D")) {
      return;
    } else {
      let result = setDestination("start", focusedController, []);
      circleArray = result.circles;
      setDestinationBtn.classList.add("once-D");
      console.log("여기", circleArray);
      setDestination("delete", focusedController, []);
    }
  };

  setDestinationBtn.addEventListener(
    "change",
    (e) => {
      setDestinationFunc(e);
    },
    true
  );
// 이벤트 리스너를 등록하는 함수
const setDestination = (param, idNum, circleArray) => {
  var drawingFlag = false; // 원이 그려지고 있는 상태를 가지고 있을 변수입니다
  var centerPosition; // 원의 중심좌표 입니다
  var drawingCircle; // 그려지고 있는 원을 표시할 원 객체입니다
  var drawingLine; // 그려지고 있는 원의 반지름을 표시할 선 객체입니다
  var drawingOverlay; // 그려지고 있는 원의 반경을 표시할 커스텀오버레이 입니다
  // var drawingDot; // 그려지고 있는 원의 중심점을 표시할 커스텀오버레이 입니다
  var circles = circleArray;

  //var circles = []; // 클릭으로 그려진 원과 반경 정보를 표시하는 선과 커스텀오버레이를 가지고 있을 배열입니다

  console.log(
    "setDestination",
    isClicked,
    typeof idNum,
    idNum,
    circleArray,
    map.o.click
  );

  if (param === "start") {
    addListener();

    //isClicked = true;
    console.log("start1", circles);
  } else if (param === "delete") {
    removeCircles();
    kakao.maps.event.removeListener(map, "click", clickFunc);
    kakao.maps.event.removeListener(map, "mousemove", mousemoveFunc);
    kakao.maps.event.removeListener(map, "rightclick", rightClick);
  } else if (param === "remove") {
    kakao.maps.event.removeListener(map, "click", clickFunc);
    kakao.maps.event.removeListener(map, "mousemove", mousemoveFunc);
    kakao.maps.event.removeListener(map, "rightclick", rightClick);
  }

  function removeListener() {
    kakao.maps.event.removeListener(map, "click", clickFunc);
    kakao.maps.event.removeListener(map, "mousemove", mousemoveFunc);
    kakao.maps.event.removeListener(map, "rightclick", rightClick);
  }

  function addListener() {
    kakao.maps.event.addListener(map, "click", clickFunc);
    kakao.maps.event.addListener(map, "mousemove", mousemoveFunc);
    kakao.maps.event.addListener(map, "rightclick", rightClick);
  }

  // 지도에 클릭 이벤트를 등록합니다
  function clickFunc(mouseEvent) {
    // 클릭 이벤트가 발생했을 때 원을 그리고 있는 상태가 아니면 중심좌표를 클릭한 지점으로 설정합니다
    if (!drawingFlag) {
      // 상태를 그리고있는 상태로 변경합니다
      drawingFlag = true;

      // 원이 그려질 중심좌표를 클릭한 위치로 설정합니다
      centerPosition = mouseEvent.latLng;

      // 그려지고 있는 원의 반경을 표시할 선 객체를 생성합니다
      if (!drawingLine) {
        drawingLine = new kakao.maps.Polyline({
          strokeWeight: 3, // 선의 두께입니다
          strokeColor: "#00a0e9", // 선의 색깔입니다
          strokeOpacity: 1, // 선의 불투명도입니다 0에서 1 사이값이며 0에 가까울수록 투명합니다
          strokeStyle: "solid", // 선의 스타일입니다
        });
      }

      // 그려지고 있는 원을 표시할 원 객체를 생성합니다
      if (!drawingCircle) {
        drawingCircle = new kakao.maps.Circle({
          strokeWeight: 1, // 선의 두께입니다
          strokeColor: "#00a0e9", // 선의 색깔입니다
          strokeOpacity: 0.1, // 선의 불투명도입니다 0에서 1 사이값이며 0에 가까울수록 투명합니다
          strokeStyle: "solid", // 선의 스타일입니다
          fillColor: "#00a0e9", // 채우기 색깔입니다
          fillOpacity: 0.2, // 채우기 불투명도입니다
        });
      }

      // 그려지고 있는 원의 반경 정보를 표시할 커스텀오버레이를 생성합니다
      if (!drawingOverlay) {
        drawingOverlay = new kakao.maps.CustomOverlay({
          xAnchor: 0,
          yAnchor: 0,
          zIndex: 1,
        });
      }
    }
  }

  // 지도에 마우스무브 이벤트를 등록합니다
  // 원을 그리고있는 상태에서 마우스무브 이벤트가 발생하면 그려질 원의 위치와 반경정보를 동적으로 보여주도록 합니다
  function mousemoveFunc(mouseEvent) {
    // 마우스무브 이벤트가 발생했을 때 원을 그리고있는 상태이면
    if (drawingFlag) {
      // 마우스 커서의 현재 위치를 얻어옵니다
      var mousePosition = mouseEvent.latLng;

      // 그려지고 있는 선을 표시할 좌표 배열입니다. 클릭한 중심좌표와 마우스커서의 위치로 설정합니다
      var linePath = [centerPosition, mousePosition];

      // 그려지고 있는 선을 표시할 선 객체에 좌표 배열을 설정합니다
      drawingLine.setPath(linePath);

      // 원의 반지름을 선 객체를 이용해서 얻어옵니다
      var length = drawingLine.getLength();

      if (length > 0) {
        // 그려지고 있는 원의 중심좌표와 반지름입니다
        var circleOptions = {
          center: centerPosition,
          radius: length,
        };

        // 그려지고 있는 원의 옵션을 설정합니다
        drawingCircle.setOptions(circleOptions);

        // 반경 정보를 표시할 커스텀오버레이의 내용입니다
        var radius = Math.round(drawingCircle.getRadius()),
          content =
            '<div class="info">반경 <span class="number">' +
            radius +
            "</span>m</div>";

        // 반경 정보를 표시할 커스텀 오버레이의 좌표를 마우스커서 위치로 설정합니다
        drawingOverlay.setPosition(mousePosition);

        // 반경 정보를 표시할 커스텀 오버레이의 표시할 내용을 설정합니다
        drawingOverlay.setContent(content);

        // 그려지고 있는 원을 지도에 표시합니다
        drawingCircle.setMap(map);

        // 그려지고 있는 선을 지도에 표시합니다
        drawingLine.setMap(map);

        // 그려지고 있는 원의 반경정보 커스텀 오버레이를 지도에 표시합니다
        drawingOverlay.setMap(map);
      } else {
        drawingCircle.setMap(null);
        drawingLine.setMap(null);
        drawingOverlay.setMap(null);
      }
    }
  }

  // 지도에 마우스 오른쪽 클릭이벤트를 등록합니다
  // 원을 그리고있는 상태에서 마우스 오른쪽 클릭 이벤트가 발생하면
  // 마우스 오른쪽 클릭한 위치를 기준으로 원과 원의 반경정보를 표시하는 선과 커스텀 오버레이를 표시하고 그리기를 종료합니다

  function rightClick(mouseEvent) {
    // result = returnDestination();

    if (drawingFlag) {
      // 마우스로 오른쪽 클릭한 위치입니다
      var rClickPosition = mouseEvent.latLng;

      // 원의 반경을 표시할 선 객체를 생성합니다
      var polyline = new kakao.maps.Polyline({
        path: [centerPosition, rClickPosition], // 선을 구성하는 좌표 배열입니다. 원의 중심좌표와 클릭한 위치로 설정합니다
        strokeWeight: 3, // 선의 두께 입니다
        strokeColor: "#00a0e9", // 선의 색깔입니다
        strokeOpacity: 1, // 선의 불투명도입니다 0에서 1 사이값이며 0에 가까울수록 투명합니다
        strokeStyle: "solid", // 선의 스타일입니다
      });

      // 원 객체를 생성합니다
      var circle = new kakao.maps.Circle({
        center: centerPosition, // 원의 중심좌표입니다
        radius: polyline.getLength(), // 원의 반지름입니다 m 단위 이며 선 객체를 이용해서 얻어옵니다
        strokeWeight: 1, // 선의 두께입니다
        strokeColor: "#00a0e9", // 선의 색깔입니다
        strokeOpacity: 0.1, // 선의 불투명도입니다 0에서 1 사이값이며 0에 가까울수록 투명합니다
        strokeStyle: "solid", // 선의 스타일입니다
        fillColor: "#00a0e9", // 채우기 색깔입니다
        fillOpacity: 0.2, // 채우기 불투명도입니다
      });
      console.log("centerPosition", centerPosition);
      const lat = document.getElementById("Lat-" + "CO_" + idNum);
      const len = document.getElementById("Len-" + "CO_" + idNum);
      lat.innerHTML =
        "<p>" + "Lat" + "</p>" + "<p>" + centerPosition.La + "</p>";
      len.innerHTML =
        "<p>" + "Len" + "<p>" + "</p>" + centerPosition.Ma + "</p>";
      var radius = Math.round(circle.getRadius()), // 원의 반경 정보를 얻어옵니다
        content = getTimeHTML(radius); // 커스텀 오버레이에 표시할 반경 정보입니다
      const radiusText = (document.getElementById(
        "Radius-" + "CO_" + idNum
      ).innerHTML = "<p>" + "반경" + "</p>" + "<p>" + radius + "</p>");

      // 액션으로 스토어 변경하기
      useStore.getState().addState({
        ["CO_" + idNum]: { id: idNum, coor: centerPosition, radius },
      });
      // 반경정보를 표시할 커스텀 오버레이를 생성합니다
      var radiusOverlay = new kakao.maps.CustomOverlay({
        content: content, // 표시할 내용입니다
        position: rClickPosition, // 표시할 위치입니다. 클릭한 위치로 설정합니다
        xAnchor: 0,
        yAnchor: 0,
        zIndex: 1,
      });

      // 원을 지도에 표시합니다
      circle.setMap(map);

      // 선을 지도에 표시합니다
      polyline.setMap(map);

      // 반경 정보 커스텀 오버레이를 지도에 표시합니다
      radiusOverlay.setMap(map);

      // 배열에 담을 객체입니다. 원, 선, 커스텀오버레이 객체를 가지고 있습니다
      var radiusObj = {
        polyline: polyline,
        circle: circle,
        overlay: radiusOverlay,
      };

      // 배열에 추가합니다
      // 이 배열을 이용해서 "모두 지우기" 버튼을 클릭했을 때 지도에 그려진 원, 선, 커스텀오버레이들을 지웁니다
      circles.push(radiusObj);
      console.log("circles", circles);
      // 그리기 상태를 그리고 있지 않는 상태로 바꿉니다
      drawingFlag = false;
      // 중심 좌표를 초기화 합니다
      centerPosition = null;

      // 그려지고 있는 원, 선, 커스텀오버레이를 지도에서 제거합니다
      drawingCircle.setMap(null);
      drawingLine.setMap(null);
      drawingOverlay.setMap(null);
    }
    kakao.maps.event.removeListener(map, "click", clickFunc);
    kakao.maps.event.removeListener(map, "mousemove", mousemoveFunc);
    kakao.maps.event.removeListener(map, "rightclick", rightClick);
    const setDestinationBtn = document.getElementById(
      "destination-radio-" + "CO_" + idNum
    );
    setDestinationBtn.disabled = false;
    const setPathBtn = document.getElementById("path-radio-" + "CO_" + idNum);
    setPathBtn.disabled = false;
    //setDestinationBtn.checked = false;
    const deleteDestinationBtn = document.getElementById(
      "delete-destination-button-" + "CO_" + idNum
    );
    deleteDestinationBtn.disabled = false;
  }

  // 지도에 표시되어 있는 모든 원과 반경정보를 표시하는 선, 커스텀 오버레이를 지도에서 제거합니다
  function removeCircles() {
    console.log("removecircle", circles);
    for (var i = 0; i < circles.length; i++) {
      circles[i].circle.setMap(null);
      circles[i].polyline.setMap(null);
      circles[i].overlay.setMap(null);
    }
    circles = [];
  }

  // 마우스 우클릭 하여 원 그리기가 종료됐을 때 호출하여
  // 그려진 원의 반경 정보와 반경에 대한 도보, 자전거 시간을 계산하여
  // HTML Content를 만들어 리턴하는 함수입니다
  function getTimeHTML(distance) {
    // 거리와 도보 시간, 자전거 시간을 가지고 HTML Content를 만들어 리턴합니다
    var content = '<ul class="info">';
    content += "    <li>";
    content +=
      '        <span class="label">총거리</span><span class="number">' +
      distance +
      "</span>m";
    content += "    </li>";

    content += "</ul>";

    return content;
  }
  return { circles, isClicked };
};

export { setDestination };

2개 버튼의 param값이 start이면 버튼을 누르지 않아도
지도 클릭 시 이벤트가 버튼 개수만큼 등록된 상태라서 원형이 두 번 그려질 것 같은데요.

이벤트는 등록한 상태로 버튼을 눌렀을 때 원형이 그려질 수 있게
setDestination에서 버튼 클릭 시 변경될 수 있는 변수를 하나 두고
버튼을 누른 경우 해당 변수 값을 true로 변경하고 지도 클릭 이벤트에서 해당 값이 true인 경우 원을 그리고
아닌 경우는 원을 그리지 않도록 이벤트가 한 번만 실행될 수 있게 구현해 주세요.

답변 감사합니다
마우스 오른쪽 버튼을 클릭하는 함수에 removeEventListener를 추가하여 마우스 오른쪽 버튼을 클릭하는 순간 이벤트가 제거되도록 해놓아서 원은 한번만 그리게 됩니다
제가 지금 수정하고 싶은 부분은 컨트롤러를 여러개 만들어 놓았을 때 이벤트가
image
이렇게 배열로 누적이 되는데 마지막에 등록한 이벤트 리스너만 실행할 수 있는 방법을 찾고 있는 중입니다…
이벤트를 제거하면 제거가 되지 않아서요…