작업이 완료되면 일이 발생하도록 콜백을 전달하거나 프로그램의 다른 함수에서 함수를 트리거했습니다. 무언가 완료되면 함수를 직접 트리거합니다.

 var ground = "clean"; function shovelSnow(){ console.log("Cleaning Snow"); ground = "clean"; } function makeItSnow(){ console.log("It"s snowing"); ground = "snowy"; shovelSnow(); }  

하지만 저는 프로그래밍의 다양한 전략에 대해 읽고 강력하다고 이해하지만 아직 실행하지 않은 전략은 이벤트 기반입니다 (제가 읽은 방법은 “pub-sub”이라고 생각합니다). :

 var ground = "clean"; function shovelSnow(){ console.log("Cleaning Snow"); ground = "clean"; } function makeItSnow(){ console.log("It"s snowing"); ground = "snowy"; $(document).trigger("snow"); } $(document).bind("snow", shovelSnow);  

이벤트의 객관적인 강점과 약점을 이해하고 싶습니다. 기반 프로그래밍과 다른 함수 내에서 모든 함수를 호출하는 것입니다. 어떤 프로그래밍 상황에서 이벤트 기반 프로그래밍을 사용하는 것이 합리적입니까?

댓글

  • 제외로 $(document).bind('snow', shovelShow)를 사용할 수 있습니다. 익명 함수로 래핑 할 필요가 없습니다.
  • ” 반응 형 프로그래밍 “는 이벤트 기반 프로그래밍과 공통점이 많습니다.

답변

이벤트 은 최근 발생한 사건을 설명하는 알림입니다.

이벤트 기반 시스템의 일반적인 구현은 이벤트 디스패처 핸들러 기능 을 활용합니다. em> (또는 구독자 ). 디스패처는 이벤트까지 핸들러를 연결하는 API (jQuery “s bind)와 구독자에게 이벤트를 게시하는 방법 (trigger IO 또는 UI 이벤트에 대해 이야기 할 때 일반적으로 마우스 클릭과 같은 새로운 이벤트를 감지하여 디스패처로 전달하는 이벤트 루프 도 있습니다. JS-land, 디스패처 및 이벤트 루프는 브라우저에서 제공합니다.

사용자와 직접 상호 작용하는 코드 (키 누르기와 클릭에 응답)의 경우 이벤트 기반 프로그래밍 (또는 기능적 반응 형 프로그래밍 )은 거의 피할 수 없습니다. 프로그래머는 사용자가 언제 어디를 클릭할지 모르기 때문에 GUI 프레임 워크에 달려 있습니다. 또는 브라우저를 사용하여 이벤트 루프에서 사용자의 작업을 감지하고 코드를 알립니다. 이러한 유형의 인프라는 네트워킹 응용 프로그램 (cf NodeJS)에서도 사용됩니다.

이벤트를 발생시키는 예제 요 함수를 직접 호출하는 것보다 코드 에는 좀 더 흥미로운 트레이드 오프가 있습니다. 이에 대해서는 아래에서 설명하겠습니다. 주요 차이점은 이벤트 게시자 (makeItSnow)가 호출 수신자를 지정하지 않는다는 것입니다. 이는 다른 곳에 연결되어 있습니다 (예시의 bind 호출에서).이를 fire-and-forget 이라고합니다. makeItSnow는 눈이 내린다고 전 세계에 알리지 만”누가 듣고 있는지, 다음에 무슨 일이 일어나고 있는지, 언제 발생하는지는 신경 쓰지 않습니다. 단순히 메시지를 방송하고 손에서 먼지를 털어냅니다. p ” >


따라서 이벤트 기반 접근 방식은 메시지 발신자와 수신자를 분리합니다. 이것이 제공하는 한 가지 장점은 주어진 이벤트에 여러 핸들러가있을 수 있다는 것입니다. 기존 shovelSnow 핸들러에 영향을주지 않고 gritRoads 함수를 눈 이벤트에 바인딩 할 수 있습니다. 응용 프로그램을 연결하는 방식에 유연성이 있습니다. 비헤이비어를 끄려면 코드를 검색하여 비헤이비어의 모든 인스턴스를 찾는 대신 bind 호출을 제거하면됩니다.

다른 이점 이벤트 중심 프로그래밍은 교차 우려를 제기 할 수있는 곳을 제공한다는 것입니다. 이벤트 디스패처는 중재자 역할을하며 일부 라이브러리 (예 : Brighter )는 로깅 또는 서비스 품질과 같은 일반적인 요구 사항을 쉽게 플러그인 할 수있는 파이프 라인입니다.

전체 공개 : Brighter는 제가 일하는 Huddle에서 개발되었습니다.

이벤트 발신자와 수신자를 분리하는 세 번째 이점은 이벤트를 언제 처리 할 때 유연성을 제공한다는 것입니다. 각 유형의 이벤트를 자체 스레드에서 처리하거나 (이벤트 디스패처가 지원하는 경우) RabbitMQ 와 같은 메시지 브로커에 발생한 이벤트를 넣을 수 있습니다. 비동기식 프로세스로 처리하거나 밤새 대량으로 처리 할 수도 있습니다. 이벤트의 수신자는 별도의 프로세스에 있거나 별도의 시스템에있을 수 있습니다. 이를 위해 이벤트를 발생시키는 코드를 변경할 필요가 없습니다. 이것이 “마이크로 서비스”아키텍처의 핵심 아이디어입니다. 자율 서비스는 이벤트를 사용하여 통신하고 메시징 미들웨어를 애플리케이션의 백본으로 사용합니다.

이벤트 중심 스타일의 다소 다른 예를 보려면 도메인 중심 디자인을 살펴보세요. 여기서 도메인 이벤트 는 골재를 분리하는 데 사용됩니다. 예를 들어, 구매 내역을 기반으로 제품을 추천하는 온라인 상점을 생각해보십시오. CustomerShoppingCart 비용을 지불 할 때 구매 내역을 업데이트해야합니다. ShoppingCart 집계는 CheckoutCompleted 이벤트를 발생시켜 Customer에 알릴 수 있습니다. Customer는 이벤트에 대한 응답으로 별도의 트랜잭션으로 업데이트됩니다.


이 이벤트 기반 모델의 주요 단점은 간접적입니다. IDE를 사용하여 탐색 할 수 없기 때문에 이벤트를 처리하는 코드를 찾기가 더 어렵습니다. 구성에서 이벤트가 바인딩되는 위치를 파악하고 모든 핸들러를 “찾았 으면합니다.”언제든지 머릿속에 보관할 항목이 더 있습니다. 여기에서 코드 스타일 규칙이 도움이 될 수 있습니다 (예 : bind에 대한 모든 호출을 하나의 파일에 넣음). 제 정상 하나의 이벤트 디스패처 만 사용하고 일관되게 사용하는 것이 중요합니다.

또 다른 단점은 이벤트를 리팩터링하기 어렵다는 것입니다. 이벤트 형식을 변경해야하는 경우 모든 수신자도 변경해야합니다. 이벤트 구독자가 다른 시스템에있을 때 더욱 악화됩니다. 이제 소프트웨어 릴리스를 동기화해야하기 때문입니다!

특정 상황에서는 성능이 문제가 될 수 있습니다. 메시지를 처리 할 때 디스패처는 다음을 수행해야합니다.

  1. 일부 데이터 구조에서 올바른 핸들러를 찾습니다.
  2. 각 핸들러에 대한 메시지 처리 파이프 라인을 구축합니다. 이것은 많은 메모리 할당을 포함 할 수 있습니다.
  3. 동적으로 핸들러를 호출합니다 (언어에서 필요로하는 경우 리플렉션을 사용할 수 있음).

이것은 일반 함수보다 확실히 느립니다. 스택에 새 프레임을 밀어 넣기 만하는 호출입니다. 그러나 이벤트 중심 아키텍처가 제공하는 유연성으로 인해 느린 코드를 훨씬 쉽게 분리하고 최적화 할 수 있습니다. 작업을 비동기 프로세서에 제출할 수있는 기능은 백그라운드에서 힘든 작업을 처리하는 동안 요청을 즉시 처리 할 수 있기 때문에 큰 이점입니다. 어쨌든 “DB와 상호 작용하거나 화면에 무언가를 그리면 IO 비용이 메시지 처리 비용을 완전히 휩쓸어 버릴 것입니다. 이는”조기 최적화를 피하는 경우입니다.


요약하면 이벤트는 느슨하게 결합 된 소프트웨어를 구축하는 좋은 방법이지만 비용이 들지 않습니다. 예를 들어 애플리케이션의 모든 함수 호출을 이벤트로 바꾸는 것은 실수입니다. 이벤트를 사용하여 의미있는 아키텍처 분할을 만드세요.

댓글

  • 이 답변은 5377과 동일합니다. ‘ 내가 정답으로 선택한 대답; ‘이 항목을 표시하도록 선택 항목을 변경하는 중입니다. 더 자세히 설명하기 때문입니다.
  • 속도가 이벤트 기반 코드의 중요한 단점입니까? 그럴 수있을 것 같지만 ‘ 잘 모르겠습니다.
  • @ raptortech97 확실히 그럴 수 있습니다. 특히 빨라야하는 코드의 경우 내부 루프에서 이벤트를 보내지 않는 것이 좋습니다. 다행스럽게도 이러한 상황에서는 일반적으로 수행해야 할 작업이 잘 정의되어 있으므로 ‘ 추가적으로 유연하게 이벤트 (또는 게시 / 구독 또는 관찰자)가 필요하지 않습니다. 다른 용어).
  • 또한 모든 것이 메시지 (이벤트) 인 액터 모델을 중심으로 구축 된 일부 언어 (예 : Erlang)가 있습니다. 이 경우 컴파일러는 메시지 / 이벤트를 직접 함수 호출로 구현할지 통신으로 구현할지 결정할 수 있습니다.
  • ” 성능 ” 단일 스레드 성능과 확장 성을 구분해야한다고 생각합니다. 메시지 / 이벤트는 단일 스레드 성능의 경우 더 나빠질 수 있으며 (하지만 추가 비용없이 함수 호출로 변환 될 수 있으며 더 나쁘지 않을 수 있음) 확장 성 측면에서 거의 모든 것에서 더 우수합니다. ‘ 방식 (예 : 최신 다중 CPU 및 향후 ” 다중 CPU ” 시스템에서 대규모 성능 향상을 가져올 가능성이 있음)

Answer

이벤트 기반 프로그래밍은 프로그램이 수행하는 이벤트 순서를 제어하지 않을 때 사용됩니다. 대신, 프로그램 흐름은 사용자 (예 : GUI), 다른 시스템 (예 : 클라이언트 / 서버) 또는 다른 프로세스 (예 : RPC)와 같은 외부 프로세스에 의해 지시됩니다.

예 : 일괄 처리 스크립트 무엇을해야하는지 알기 때문에 그냥합니다. 이벤트 기반이 아닙니다 .

워드 프로세서가 거기에 앉아 사용자가 입력을 시작할 때까지 기다립니다.키 누르기는 내부 문서 버퍼를 업데이트하는 기능을 트리거하는 이벤트입니다. 프로그램은 사용자가 입력하려는 내용을 알 수 없으므로 이벤트 기반이어야합니다.

대부분의 GUI 프로그램은 사용자 상호 작용을 중심으로 구축 되었기 때문에 이벤트 기반입니다. 그러나 이벤트 기반 프로그램은 GUI에만 국한되지 않으며 이는 대부분의 사람들에게 가장 친숙한 예입니다. 웹 서버는 클라이언트가 연결될 때까지 기다렸다가 유사한 관용구를 따릅니다. 컴퓨터의 백그라운드 프로세스도 이벤트에 응답 할 수 있습니다. 예를 들어, 주문형 바이러스 스캐너는 새로 생성되거나 업데이트 된 파일과 관련하여 OS로부터 이벤트를 수신 한 다음 해당 파일에서 바이러스를 검색 할 수 있습니다.

Answer

이벤트 기반 애플리케이션에서 이벤트 리스너 의 개념은 더 많은 를 작성할 수있는 기능을 제공합니다. 느슨하게 결합 된 애플리케이션.

예를 들어 타사 모듈 또는 플러그인은 데이터베이스에서 레코드를 삭제 한 다음 receordDeleted 이벤트를 수행하고 나머지는 이벤트 리스너에게 맡겨 작업을 수행합니다. 트리거 모듈이 누가이 특정 이벤트를 수신하는지 또는 다음에 무슨 일이 발생해야하는지조차 알지 못하더라도 모든 것이 잘 작동합니다.

Answer

추가하고 싶었던 간단한 비유가 도움이되었습니다.

애플리케이션의 구성 요소 (또는 개체)를 대규모 Facebook 친구 그룹으로 생각하십시오.

친구 중 한 명이 당신에게 무언가를 말하고 싶을 때 직접 전화를 걸거나 페이스 북 담벼락에 게시 할 수 있습니다. Facebook에 게시하면 누구나 보고 반응 할 수 있지만 많은 사람들이 그렇지 않습니다. 때로는 사람들이 반응해야 할 중요한 일입니다. “우리는 아기를 낳고 있습니다!”또는 “그렇게 밴드가 Drunkin에서 깜짝 콘서트를하고 있습니다. “클램 바!”. 마지막 경우에는 나머지 친구들이 반응해야 할 것입니다. 특히 그들이 그 밴드에 관심이 있다면

친구가 당신과 그들 사이에 비밀을 유지하고 싶어한다면 그들은 아마도 페이스 북 벽에 게시하지 않고 직접 전화를 걸어 말해 줄 것입니다. 좋아하는 여자에게 데이트를 위해 식당에서 만나고 싶다고 말하는 시나리오를 상상해보세요. 직접 전화를 걸어 물어 보는 대신 친구가 볼 수 있도록 Facebook 담벼락에 게시합니다.이 방법은 효과가 있지만 질투심 많은 전 애인이 있으면 그녀가 그것을보고 레스토랑에 나타나서 하루를 망칠 수 있습니다.

언제 무언가를 구현하기 위해 이벤트 리스너를 구축할지 여부를 결정하고이 비유를 생각해보십시오.이 구성 요소가 다른 사람이 볼 수 있도록 비즈니스를 내 보내야합니까? 아니면 누군가에게 직접 전화를 걸어야합니까? 상황이 매우 쉽게 지저분해질 수 있습니다. 주의하세요.

답변

다음과 같은 비유가 도움이 될 수 있습니다. 의사의 접수처에서 대기 줄과 평행선을 그려 이벤트 중심 I / O 프로그래밍을 이해합니다.

I / O 차단은 대기열에 서 있으면 접수 원이 앞의 사람에게 양식을 작성 해달라고 요청하고 완료 될 때까지 기다립니다. 당신은 그 남자가 자신의 폼을 끝낼 때까지 당신의 차례를 기다려야합니다. 이것은 블로킹입니다.

싱글 남자가 3 분을 채우면, 10 번째 남자는 30 분까지 기다려야합니다. 이제이 10 번째 사람의 대기 시간을 줄이기 위해 해결책은 접수 원의 수를 늘리는 것입니다. 이는 비용이 많이 듭니다. 이것은 기존의 웹 서버에서 일어나는 일입니다. 사용자 정보를 요청하면 다른 사용자의 후속 요청이있을 때까지 기다려야합니다. 현재 작업 인 데이터베이스에서 가져 오기가 완료되었습니다. 이로 인해 10 번째 요청의 “응답 시간”이 증가하고 n 번째 사용자에 대해 기하 급수적으로 증가합니다. 이러한 전통적인 웹 서버를 피하기 위해 모든 단일 요청에 대해 스레드 (접수자 수가 증가하는 것과 동일)가 생성됩니다. 즉, 기본적으로 모든 요청에 운영 체제 스레드가 필요하기 때문에 CPU 소비 측면에서 비용이 많이 드는 각 요청에 대해 서버 사본을 생성합니다. 앱을 확장하려면 앱에 많은 계산 능력을 투입해야합니다. .

이벤트 기반 : 대기열의 “응답 시간”을 확장하는 다른 방법은 다음과 같습니다. 이벤트 중심의 접근 방식으로 이동합니다. 대기열에있는 사람은 양식을 작성하고 완료하면 다시 오십시오. 따라서 접수 원은 항상 요청을받을 수 있습니다. 이것이 바로 자바 스크립트가 처음부터 해왔 던 일입니다. 브라우저에서 자바 스크립트는 사용자 클릭 이벤트, 스크롤, 스 와이프 또는 데이터베이스 가져 오기 등에 응답합니다. 자바 스크립트는 함수를 일등급으로 취급하기 때문에 자바 스크립트에서 본질적으로 가능합니다. 객체는 매개 변수로 다른 함수 (콜백이라고 함)에 전달 될 수 있으며 특정 작업 완료시 호출 될 수 있습니다. 이는 정확히 node.js가 서버에서 수행하는 작업입니다.이벤트 기반 프로그래밍 및 차단 I / O에 대한 자세한 정보는 여기

노드 컨텍스트에서 확인할 수 있습니다.

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다