동적이고 추상적인 이벤트 객체를 쉽게 이해할 수 있도록 도와주실 수 있나요?

StackOverflow https://stackoverflow.com/questions/471144

  •  19-08-2019
  •  | 
  •  

문제

저는 GUI 버튼용 MFC를 사용하여 C++ 이벤트 기반 앱을 작성했으며 onmousedown과 같은 HTML 이벤트를 사용하여 웹 페이지에서 일부 Javascript를 트리거합니다.이벤트 기반 프로그래밍의 아이디어는 인터페이스를 사용할 때 직관적이며 이벤트는 하드 코딩됩니다.

나는 C에서 함수 포인터를 사용하는 방법을 알고 있으며 Windows가 이를 사용하여 이벤트 루프를 실행하는 방법을 알고 있습니다.다른 함수를 동적으로 호출하는 코드를 작성할 수 있습니다.

내 문제는 컴파일 타임에서 런타임으로 이동하는 것입니다.여기서는 어떤 언어든 말하지만, 언어가 필요하다면 제가 요즘 가장 많이 사용하는 자바스크립트나 PHP를 선택하세요.나는 내 이벤트 개체를 사용하여 작업을 수행하는 방법을 전혀 이해하지 못합니다.그것은 내가 이해하는 개념이 아닙니다.그리고 나는 그것들을 사용하지 않기 때문에 그것들의 실제 용도가 무엇인지 모르겠습니다.

예를 들어, 맞춤형 턴 기반 게임을 만들고 싶다면 이벤트 개체를 사용하여 "발생"해야 하는 일부 게임 기능의 효과를 나타낼 수 있다고 가정합니다.

누군가 나에게 맞춤 이벤트를 간단하게 사용할 수 있는 방법을 알려줄 수 있나요?아니면 유용하거나 실용적인 상황인가요?언어와 환경, 이벤트 처리 방법에 따라 크게 달라지나요?Javascript 답변이 좋겠지만 많은 언어를 읽었습니다.

죄송합니다. 저는 이 점에 있어서 부족하고 실용적이고 고급(중급?) 통찰력이 필요합니다.C의 포인터와 같습니다.나는 포인터를 "얻고" 그것이 당신의 친구라는 사실을 알게 됩니다.하지만 내가 그러지 않았던 때가 있었고, 내가 아는 많은 사람들은 아직도 그렇지 않습니다.일단 얻으면 간단합니다. 저는 그런 식으로 맞춤화된 동적 이벤트를 얻지 못합니다.

도움이 되었습니까?

해결책

이벤트 지향 프로그래밍에 대해 이야기할 때 일반적으로 하나 이상의 구현에 대해 이야기합니다. 관찰자 디자인 패턴.관찰자 디자인 패턴의 목표 중 하나는 다음과 같습니다. 느슨한 결합 객체 사이.

아마도 좋은 예가 없으면 큰 의미가 없을 것입니다. 그리고 확실히 좋은 예가 많이 있습니다.내 것이 그 중 최고가 될지는 의심스럽습니다. 하지만 그럼에도 불구하고 한번 시도해 보겠습니다.두 개의 물체를 상상해보십시오.한 개체는 다른 개체에 무슨 일이 일어났는지 알고 싶어하므로 스스로 뭔가를 할 수 있습니다. 아마도 가족 개인 누렁이는 아빠가 직장에서 집에 돌아오면 문앞에서 인사하고 싶어할 수도 있습니다.해당 시나리오를 프로그래밍할 수 있는 방법에는 몇 가지가 있습니다. 그렇죠?

  • 아빠가 Rover에 대한 참조를 가지고 있는지 확인하고 집에 돌아오면 Rover의 GreetingDatAtTheDoor() 메서드를 호출하세요.

  • 로버에게 아빠에 대한 참조를주고, 아빠의 onarrivehome 이벤트를 듣고, 해고되면 내부적으로 greetdadatthedoor ()에게 전화하십시오.

표면적으로는 둘 사이에 큰 차이가 없는 것처럼 보일 수도 있지만 실제로 아빠는 Rover의 구현 중 일부를 그 안에 포함하고 있습니다.어떤 이유로 Rover의 구현을 변경해야 한다면 다음 두 곳을 변경해야 합니다.Rover에서 한 번, 그리고 Dad에서 다시.큰 문제는 아닐 수도 있지만 여전히 이상적이지는 않습니다.

이제 엄마가 아빠에게도 인사하고 싶어한다고 상상해보세요.그리고 고양이 씨.아빠를 별로 좋아하지 않는 비글스워스는 아빠가 주변에 없는지 확인하고 싶어서 밖으로 나가는 것을 더 좋아합니다.그리고 이웃인 조(Joe)는 아빠가 언제 집에 오시는지 알고 싶어 합니다. 그래서 아빠가 그에게 빚진 20달러에 대해 그를 괴롭힐 수 있습니다.이러한 모든 시나리오와 필연적으로 발생하는 추가 시나리오를 어떻게 설명합니까?엄마의 GreetingHusband() 메서드, 고양이의 getOutNow() 메서드, 강아지의 GreetingDadAtTheDoor() 메서드 및 Joe의 goGetMyMoney() 메서드에 대한 참조를 아빠의 클래스 정의에 배치하면 아빠의 일이 빨리 망가질 것입니다. 아빠가 꼭 해야 할 일이 스스로 집에 돌아오셨습니다.엄마, 개, 고양이, 이웃은 그런 일이 발생하면 알림을 받고 싶어하므로 내부 구현에서 요구하는 모든 작업을 수행할 수 있습니다.

언어는이 내용의 세부 사항을 다양한 방식으로 처리하지만, 인터넷 검색을 시작할 때 알 수 있듯이 패턴은 일반적으로 "Dispatcher"이벤트에 배열 또는 어레이와 같은 구조가 포함됩니다 (이 경우 DAD. - 즉, 다른 모든 사람이 관심이있는 대상) 및 "가입자"(예 : 엄마, 고양이, 로버 및 조)는 모두 파견자에 공개적으로 노출 된 방법을 호출하고 스스로 참조를 전달하여 "등록"합니다. - 아빠의 "가입자"배열에서 어떤 형태로든 끝나는 참조. 그런 다음 아빠가 집에 돌아 오면 "나는 집에"이벤트를 "파견"합니다. 이벤트는 이벤트 - 본질적으로 각 구독자를 루프하고 공개적으로 액세스 할 수있는 방법으로 호출하는 기능입니다. 아빠라는 이름을 알지 못하는 방법은 알 필요가 없습니다. 청취자는 통과했을 때 그것을 제공했습니다.

요즘에는 주로 ActionScript를 코딩하므로 내 세계에서는 다음과 같이 보일 수 있습니다. 예를 들어 Mom 클래스 내에서 선언된 대로입니다.

var dad:Dad = new Dad();
dad.addEventListener(DadEvent.ARRIVED_HOME, greetHusbandAtDoor);

private function greetHusbandAtDoor(event:DadEvent):void
{
   // Go greet my husband
}

그러면 아빠가 집에 돌아와서 해야 할 일은 다음과 같습니다.

dispatchEvent(new DadEvent(DadEvent.ARRIVED_HOME));

...그리고 Flash가 나를 위해 이벤트 전달 및 알림 세부 정보를 처리하기 때문에(다시 말하지만 모든 사람이 처리하는 방식은 약간 다르지만 내부적으로 Flash는 내가 설명한 개념 모델을 따릅니다.) 아버지가 집에 오시면 각 가족 구성원이 서명한 대로 수행합니다. 자동으로 할 수 있게 되었습니다.

이벤트 사고 방식, 느슨한 결합의 의미, 그것이 중요한 이유 등을 조금 설명할 수 있기를 바랍니다.행운을 빌어 요!

다른 팁

컴파일된 언어에서는 자신만의 이벤트 루프를 작성합니다.런타임 언어에서는 이미 호스트 환경에 의해 구현되어 있으며 프로그래머는 이벤트 시스템에 추상화된 인터페이스만 가져옵니다.이벤트 루프가 표시되지 않습니다.

이벤트로 기능을 구축하는 데에는 두 가지 측면이 있습니다.첫 번째는 이벤트가 실행되는 조건을 정의하는 것입니다.브라우저의 자바스크립트에는 단일 "mousedown" 이벤트가 없습니다.실제로 페이지의 모든 요소마다 하나씩 있습니다.이 경우, 이들 중 하나가 실행되는 시기에 대한 조건은 마우스 커서의 위치와 마우스 버튼이 방금 업 상태에서 다운 상태로 전환되었는지 여부에 따라 달라집니다.이 조건으로 인해 여러 이벤트가 발생할 수 있습니다.(브라우저에는 이와 관련된 이벤트 "버블링"이라는 것이 있습니다.하지만 여기서는 범위를 벗어납니다.)

다른 측면은 이벤트 핸들러입니다.이벤트는 해당 핸들러가 있는지 여부에 관계없이 발생합니다.핸들러 제공은 귀하에게 달려 있습니다.자바스크립트에서 함수는 일급 값입니다.컴파일 타임이 아닌 런타임에 정의됩니다. 따라서 포인터나 점프 테이블이 필요하지 않습니다.런타임에 새 기능을 생성하고 특정 이벤트가 발생할 때 호스트 환경이 조회하는 특수 속성에 이를 할당합니다.

따라서 스택 오버플로 시 아래쪽 화살표의 "onclick" 이벤트 각각에 이벤트 핸들러가 있을 것입니다. 이 이벤트 핸들러는 화살표를 빨간색으로 바꾸고 숫자를 감소시키며 다른 변수를 확인하고 조건에 따라 알림을 표시합니다.그런 다음 핸들러가 반환되면 스레드 제어를 브라우저에 반환하고 할렐루야 사용자는 브라우저와 다시 상호 작용할 수 있습니다.(이벤트가 처리되는 동안 모든 상호작용이 중단되므로 빠르게 처리하는 것이 좋습니다.)다음은 jquery 라이브러리를 사용하는 예입니다.

jQuery("a .downarrow")
.click(function(e){ e.target.style.color="red" /* ... do other things */ });

또는 원시 자바스크립트(버전 1.6)에서는 다음과 같을 수 있습니다.

Array.prototype.slice.apply(document.getElementsByTagName("a"))
.filter(function(o){ return !!(/downarrow/).exec(o.className)})
.forEach(function(o){ 
    o.onclick= function(e){ 
        e.target.style.color="red" /* ...do other things * / 
    }
 });

정말 간단합니다.이와 같은 작업을 수행하는 주된 이유는 비동기식 상호 작용이 가능하기 때문입니다.GUI 애플리케이션은 단계별로 직선으로 진행되지 않습니다.사용자의 입력에 동적으로 반응해야 합니다.이벤트는 멀티스레드 애플리케이션의 모습을 가짜로 만드는 방법입니다.사용자에게는 서로 방해하지 않고 동시에 많은 일이 일어나고 있는 것처럼 보일 수 있습니다.

라이브러리를 사용하여 맞춤 이벤트를 정의할 수 있습니다.이는 아마도 일부 도메인 특정 이벤트를 인코딩할 수 있습니다.예를 들어:다음 수를 생각하고 있는 체스 게임이 있습니다.이동을 검색하는 프로세스에 시간이 부족합니다.체스 게임에서는 "onComputerMove" 이벤트가 발생할 수 있습니다.이동 사양을 파악하고 체스판의 시각적 표현을 업데이트하며 사용자에게 메시지를 표시하고 종료하는 함수를 사용하여 해당 이벤트를 처리할 수 있습니다.그런 다음 플레이어가 움직일 때 거의 동일한 작업을 수행하는 "onPlayerMove" 이벤트를 실행할 수 있습니다.

이벤트의 가장 놀라운 점은 두 모듈이나 클래스 간의 명시적인 양방향 결합을 줄이는 것입니다.

그럼 두 가지 수업이 있다고 가정해 보겠습니다.아기와 엄마


이벤트 없이 엄마가 아기에게 젖을 먹일 수 있도록 하는 방법은 대략 두 가지입니다.

  • 엄마가 전화해 baby.pokeBelly() 전화해야 하는지 알아보기 위해 매 30분마다 아기에게 방법을 알려줍니다. baby.fillWith(milk).
    문제는 엄마의 스레드가 while 루프에서 아기를 낳은 후 하루 종일 기다려야 한다는 것입니다.
  • 아기는 자신과 관련된 엄마를 알고 전화를 겁니다. mommy.feed(me) 메서드는 차례로 호출됩니다. baby.fillWith(milk).
    문제는 단순한 아기에게 올바른 엄마에게 배를 채워달라고 요청하는 것입니다.
    아기들은 단순함을 유지해야 하기 때문에 그렇게 하지 않습니다.

이벤트를 사용하면 Mommy.OnBabyCries(baby) 그 아기에게 baby.Cry 이벤트:

void Mommy.OnBabyCries(baby) {
    baby.fillWith(milk)
}

그 후, 아기가 먹고 싶어하면 Cry 이벤트를 발생시키기만 하면 됩니다.

논리는 Mommy에 유지되거나 나중에 Babysitter에 유지되며 Baby는 걱정할 필요 없이 행복하게 유지됩니다.

귀하의 질문을 완전히 이해했는지는 모르겠지만 이벤트가 있는 클래스는 버튼이 있는 GUI와 같습니다.그냥 호몬쿨루스처럼 생각해보세요... 이벤트가 있는 모든 수업 내부에는 누를 수 있는 가상 버튼이 있는 작은 사람이 있습니다.그는 버튼이 무엇을 할지는 모르지만 언제 눌러야 할지 알고 있습니다.이제 또 다른 작은 사람이 있는 관련 수업을 생각해 보세요.그 사람은 버튼을 눌렀다는 메시지를 들으면 자신이 뭔가를 해야 한다는 것을 알고 있습니다.

첫 번째 사람이 한 일에 대해 두 번째 사람이 알기를 원할 때마다 첫 번째 수업과 두 번째 수업 사이의 교환대를 연결합니다(이벤트 구독).첫 번째 사람이 버튼을 누르면(이벤트 발생) 두 번째 사람은 자신이 해야 할 일을 무엇이든 합니다.

이것이 도움이 되는지, 아니면 내 프로그램에 나오는 작은 사람들을 생각하면서 산성 여행을 하고 있는지는 모르겠습니다...

~에 StackOverflow, 반대 투표를 하면 평판이 떨어지고 아래쪽 화살표가 빨간색으로 변합니다.

보통은 한줄씩 쓰는데 onclick, 그 안의 모든 요소를 ​​업데이트하고 페이지 레이아웃이 변경될 때마다 변경하는 것을 잊지 마십시오.

대신에 선언할 수 있습니다. onVoteDown 이벤트, 시작하세요 onclick 이 이벤트를 구독하세요:

  • 당신의 평판 div
  • 너의 화살 img
  • 당신의 XmlHTTPRequest 귀하의 투표를 서버로 보냅니다.

귀하가 어떤 종류의 답변을 찾고 있는지 잘 모르겠습니다. 따라서 이것이 가까운 답변이 아니라면 사과드립니다.;)


에 의해 관습, 그런 뜻인가요? 맞춤 작업, 맞춤 트리거, 또는 정말로 맞춤 이벤트?

예:ㅏ 맞춤 작업 미리 정의된 이벤트(예: 마우스 클릭)에 응답합니다. 맞춤 트리거 스크립트를 통해 마우스 클릭을 속이는 것입니다. 맞춤 이벤트 언어로 정의되지 않았거나 쉽게 사용할 수 없는 청취자가 될 것입니다.

찾고 계시다면 맞춤 이벤트, 나는 당신을 정말로 도울 수 없습니다.하지만 JavaScript에서는 이에 대한 지원이 많지 않다고 생각합니다.


정의하려면 행동...

이벤트는 일반적으로 객체의 미리 정의된 속성을 통해 설정됩니다. window.onload.기본적으로 이들은 모두 다음과 같습니다. undefined 또는 null.따라서 이를 사용하려면 함수의 값으로 설정해야 합니다.

"익명" 기능을 사용할 수 있습니다.

window.onload = function (eventObject) {
    /* ... */
};

또는 함수 참조로 설정합니다(동일하지는 않지만 포인터와 유사).

function handleOnload(eventObject) {
    /* ... */
}

window.onload = handleOnload; /* note the lack of parenthesis */

이벤트가 트리거되면 함수가 호출됩니다.따라서 어느 설정에서든 페이지 로드가 완료되면 대신에 배치한 코드가 /* ... */ 실행됩니다.

이벤트를 생성하는 데 사용할 수 있는 보다 공식적인 방법도 있습니다.W3C는 정의합니다 addEventListener IE가 사용하는 동안 attachEvent. 더 많은 정보.

사용 가능한 이벤트 목록을 알아보는 데 사용할 수 있는 참조 자료가 많이 있습니다.다음은 좋은 기반을 제공하는 2가지입니다.


브라우저는 일반적으로 브라우저 이벤트(onload) 또는 사용자 이벤트(onclick).속성과 함수는 응답을 의미합니다.

트리거링 자신의 이벤트는 달성하기 가장 쉬운 일이 아닙니다.완전히 정의하려면 Event 객체에는 약간의 작업이 필요합니다. 브라우저마다 다름.

그래도 필요하지 않다면 Event 객체의 경우 간단히 이벤트를 호출할 수 있습니다.

window.onload();
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top