programing

angularJS $on 이벤트 핸들러 트리거 순서

stoneblock 2023. 11. 5. 10:51

angularJS $on 이벤트 핸들러 트리거 순서

나는 두가지를 궁금했어요, 각도의JS 이벤트 처리.

  1. 동일한 이벤트를 청취하는 핸들러가 트리거되는 순서는 어떻게 정의됩니까?
  2. 이것에 대해 궁금증을 가지기 시작하면 디자인이 좋지 않다는 신호입니까?

$on, $broadcast 및 $emit에 대한 설명서와 네이티브 DOM 이벤트 흐름을 읽고 어떤 순서로 이벤트 핸들러가 다른 범위에서 트리거되는지 이해했다고 생각합니다.문제는 여러 핸들러가 동일한 범위(예: rootScope)에서 다양한 장소(예: Controller vs Services)에서 수신하는 경우입니다.

문제를 설명하기 위해 하나의 컨트롤러와 두 개의 서비스로 jsfiddle을 구성했으며 모두 $rootScope http://jsfiddle.net/Z84tX/ 을 통해 통신했습니다.

Thanks

아주 좋은 질문입니다.

이벤트 핸들러는 초기화 순서대로 실행됩니다.

제 핸들러들이 어떤 핸들러가 먼저 실행되는지 알 필요가 없었기 때문에 이 문제에 대해 별로 생각해 본 적이 없지만, 핸들러들이 초기화되는 순서대로 호출되는 것을 볼 수 있습니다.

당신은 조종 장치를 가지고 있습니다.controllerA두가지 서비스에 달려있는거죠ServiceA그리고.ServiceB:

myModule
  .controller('ControllerA', 
    [
      '$scope', 
      '$rootScope', 
      'ServiceA', 
      'ServiceB', 
      function($scope, $rootScope, ServiceA, ServiceB) {...}
    ]
  );

서비스와 컨트롤러 모두 이벤트 수신기를 정의합니다.

이제 모든 종속성을 해결한 후 주입해야 합니다. 즉, 컨트롤러에 주입하기 전에 두 서비스가 모두 초기화됩니다.따라서 서비스 팩토리는 컨트롤러보다 먼저 초기화되기 때문에 서비스에 정의된 핸들러가 먼저 호출됩니다.

그러면 투입되는 순서대로 초기화가 되는 것을 볼 수 있습니다.ServiceA이전에 초기화됩니다.ServiceB그 순서대로 컨트롤러에 주입되기 때문입니다.컨트롤러 서명 내에서 순서를 변경하면 초기화 순서도 변경됩니다(ServiceB앞에 오는ServiceA).

따라서 서비스가 초기화된 후 컨트롤러도 초기화되고 이를 통해 이벤트 핸들러가 내부에 정의됩니다.

따라서 $broadcast에서 핸들러는 다음과 같은 순서로 실행됩니다.ServiceA핸들러,ServiceB핸들러,ControllerA조련사

이 경로로 가는 것은 좀 번거롭지만, 서비스 B가 서비스 A 이전에 초기화되는지 확인할 수 없고 서비스 B의 청취자가 먼저 실행되어야 하는 경우를 대비하여 대안을 제공하고자 했습니다.

당신이 조작할 수 있는 것은$rootScope.$$listeners서비스 B의 청취자를 최우선으로 하는 배열.

청취자를 에 추가할 때 이와 같은 것이 작동합니다.$rootScope서비스 중 B:

var listener, listenersArray;
$rootScope.$on('$stateChangeStart', someFunction);
listenersArray = $rootScope.$$listeners.$stateChangeStart;
listener = listenersArray[listenersArray.length - 1];
listenersArray.splice(listenersArray.length - 1, 1);
listenersArray.unshift(listener);

#2에 대한 답을 제공하기 위해(#1에 대한 @Stewie의 답이 정말 좋은 것이라고 생각하기 때문에), "이것을 보면 나쁜 코드"라는 결정적인 규칙을 제안하는 것을 망설이고 있지만, 만약 두 명의 이벤트 핸들러가 있다면,그리고 하나는 다른 하나가 실행된 후에만 실행할 수 있습니다. 왜 그런 것인지, 그리고 논리가 실행되는 방식을 더 잘 캡슐화하거나 구성할 수 없는 경우를 평가해야 합니다.

pub/sub event 브로드캐스트/리스닝의 주요 사용 사례 중 하나는 서로 완전히 독립적인 별개의 구성 요소가 그들의 영향 영역에서 비동기적인 방식으로 작동하도록 허용하는 것입니다.한 핸들러는 다른 핸들러가 먼저 실행된 후에만 작동해야 하므로 보조 요구사항을 추가하여 pub/sub의 비동기성을 제거하는 것입니다(가능한 경우 필요함).

꼭 필요한 종속성이라면 아닙니다. 디자인이 나쁘다는 증상이 아니라 해당 기능의 요구 사항에 따른 증상입니다.

Angular JS를 처음 사용하는 사용자이므로 답변이 최적에 못 미치더라도 양해 부탁드립니다. :P

이벤트에 의해 트리거된 함수의 순서를 종속적으로 설정해야 하는 경우(즉, 함수 A, 함수 B) 트리거 함수를 생성하지 않는 것이 더 나을 수 있습니다.

function trigger(event,data) {
    FunctionA(event,data);
    FunctionB(event,data);
}

$rootScope.on('eventTrigger',trigger);

2번 지점에 대한 다른 의견을 추가하려면 순서를 보장해야 할 경우 청취자 배열이 있는 서비스를 사용하여 관찰자 패턴을 구현할 수 있습니다.서비스에서 청취자가 순서를 지정하는 방법을 정의하는 "addListener" 함수를 정의할 수 있습니다.그런 다음 이벤트를 수행하는 데 필요한 다른 구성 요소에 이 서비스를 주입할 수 있습니다.

디자인에 사용하는 것은 절대 권장되지 않지만 선택의 여지가 없을 때도 있습니다.

$rootScope.$on('someEvent', () => {
    setTimeout(eventHandler1, 1);
});

$rootScope.$on('someEvent', eventHandler2);

const eventHandler1 = () => {
    console.log('This one runs last');
};

const eventHandler2 = () => {
    console.log('This one runs first');
};

예를 보시면 아시겠지만, 저는 지금까지setTimeout실제 핸들러를 실행하는 순서를 속이고 다음을 만듭니다.eventHandler1먼저 호출되었지만 마지막으로 실행할 핸들러입니다.

실행 우선 순위를 설정하려면 다음 항목을 변경합니다.setTimeout필요에 따라 연기합니다.

이는 이상적이지 않으며 특정한 경우에만 적합합니다.

언급URL : https://stackoverflow.com/questions/17451382/angularjs-on-event-handler-trigger-order