자바스크립트와 하나의 스레드?하지 않을 경우,어떻게 동기화되 공유 데이터에 대한 액세스?

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

문제

I 웹 페이지 DIVs 로 mouseover 핸들러는 것을 보여주는 팝업 정보 거품입니다.나는 원하지 않는 하나 이상의 거품 정보를 볼 수 있습니다.그러나 사용자 이동 마우스 빠르게 두 가지 이상의 항목,나는 때로는 두 개의 거품입니다.이어야,일어나지 않기 때문에 코드를 보여주는 팝업을 취소합 이전 팝업이 있습니다.

이 다중 스레드 시스템은 다음 문제는 것이 명백합니다:가 있는 두 개의 스레드를 표시하는 팝업,그리고 그들은 모두 취소 기존의 팝업 후 pop 자신의 팝업이 있습니다.그러나 나는 가정 자바 스크립트는 항상 하나의 스레드는 이를 방지합니다.내가 잘못입니까?는 이벤트는 핸들러를 실행하는 비동기식으로,어떤 경우에는 내가 필요로 동기화된 액세스를 공유된 데이터,또는 나 대신고 버그에서 라이브러리 코드가 취소 pop-ups?

편집을 추가합니다:

  • 라이브러리에서 질문 비유임 그 Ajax 라이브러리
  • 이벤트 처리기가 전화 SimileAjax.DOM.cancelEvent(domEvt), 나는 가정에 따라 이름을 취소한 버블시의 이벤트
  • 그냥콘을 사용할 수 있습니다.더 복잡하게,내가 실제로 시작 시간 제한하지 않을 경우 취소 moustout 팝업이 표시됩니다,이되는 것을 방지하기 위한 것입 팝업을 깜빡이 귀찮게 하지만 귀찮게 하는 데 반대의 효과입니다.

나는 또 다른것에 보면 나는 일할 수 있는 곳 내가 잘못입니다.:-)

도움이 되었습니까?

해결책

예, JavaScript는 단일 스레드입니다. Google Chrome과 같은 브라우저에서도 탭 당 하나의 스레드가 있습니다.

한 팝업을 다른 팝업으로 취소하려고하는 방법을 모르면 문제의 원인이 무엇인지 말하기가 어렵습니다.

당신의 div가 서로 안에 중첩되면 이벤트 전파 문제.

다른 팁

나는 당신이 사용하고있는 라이브러리를 모르지만, 한 번에 SomeSort의 툴팁 하나만 표시하려고한다면 ... Flyweight 객체를 사용하십시오. 기본적으로 플라이급은 한 번 만들고 반복해서 사용되는 것입니다. 싱글 톤 수업을 생각해보십시오. 따라서 처음 호출되면 자동으로 자체 객체를 생성하고 저장하는 클래스를 정적으로 호출합니다. 하나는 모든 정적 모든 참조가 동일한 객체를 동일한 객체로 발생하며 이로 인해 여러 툴팁이나 충돌이 발생하지 않습니다.

ExtJ를 사용하고 툴팁과 메시지 상자를 플라이급 요소로합니다. 나는 당신의 프레임 워크에 플라이급 요소가 있기를 바라고 있습니다. 그렇지 않으면 자신만의 싱글 톤을 만들어 전화해야합니다.

브라우저에 단일 스레드입니다. 이벤트 핸들러는 하나의 스레드에서 비동기 적으로 실행 중이며, 차단되지 않은 것이 다중 스레드를 의미하지는 않습니다. 당신의 divs 중 하나가 다른 자녀입니까? 사건은 어린이에서 부모로 DOM 트리의 거품처럼 퍼져 있기 때문입니다.

비슷한 pkaeding 말했다,그것은 추측하기 어려운 문제를 보지 않고 태그와 스크립트그런데,나는 말 벤는 당신이 제대로 멈추기 이벤트 전파 및/또는 당신이 제대로 되지 않을 숨기는 기존 요소입니다.내가 알지 못하는 경우 프레임워크를 사용하거나지 않지만,여기에 가능한 솔루션을 사용하여 시제품:

// maintain a reference to the active div bubble
this.oActiveDivBubble = null;

// event handler for the first div
$('exampleDiv1').observe('mouseover', function(evt) {
    evt.stop();
    if(this.oActiveDivBubble ) {
        this.oActiveDivBubble .hide();
    }
    this.oActiveDivBubble = $('exampleDiv1Bubble');
    this.oActiveDivBubble .show();

}.bind(this));

// event handler for the second div
$('exampleDiv2').observe('mouseover'), function(evt) {
    evt.stop();
    if(this.oActiveDivBubble) {
        this.oActiveDivBubble.hide();
    }
    this.oActiveDivBubble = $('exampleDiv2Bubble');
    this.oActiveDivBubble .show();
}.bind(this));

물론,이 될 수있는 일반화에 의해 추가로의 모든 요소를 얻고,말,함께 같은 클래스의 반복을 통해,그들과 동일하게 적용 이벤트 처리 기능을 각각들.

어느 방법으로,희망이 도움이 됩니다.

참고 : Firefox 3 에서이 논의와 거의 관련이있는 변경 사항이 있습니다. 실행 스레드는 동기식 XMLHTTPREQUEST 요청을 유발하는 실행 스레드가 분리됩니다 (동기 요청 중에 인터페이스가 얼지 않는 이유). 동기 요청 완료 후에도 스레드도 계속됩니다. 동시에 실행되지는 않지만 동기식 절차 (요청)가 더 이상 적용되지 않는 반면 단일 스레드가 중지된다는 가정에 의존합니다.

디스플레이가 충분히 빨리 상쾌하지 않을 수 있습니다. 사용중인 JS 라이브러리에 따라 팝업 "Show"효과에 약간의 지연이있을 수 있습니다.

작동 버전은 다음과 같습니다. 항목을 만들 때 우리는 a를 첨부합니다 mouseover 이벤트:

var self = this;
SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mouseover", function (elt, domEvt, target) {
    return self._onHover(labelElmtData.elmt, domEvt, evt);
});

이것은 타임 아웃을 설정하는 함수를 호출합니다 (다른 항목의 기존 시간 초과가 먼저 취소됩니다).

MyPlan.EventPainter.prototype._onHover = function(target, domEvt, evt) {            
    ... calculate x and y ...
    domEvt.cancelBubble = true;
    SimileAjax.DOM.cancelEvent(domEvt);
    this._futureShowBubble(x, y, evt);

    return false;
}
MyPlan.EventPainter.prototype._futureShowBubble = function (x, y, evt) {
    if (this._futurePopup) {
        if (evt.getID() == this._futurePopup.evt.getID()) {
            return;
        } else {
            /* We had queued a different event's pop-up; this must now be cancelled. */
            window.clearTimeout(this._futurePopup.timeoutID);
        } 
    }
    this._futurePopup = {
        x: x,
        y: y,
        evt: evt
    };    
    var self = this;
    this._futurePopup.timeoutID =  window.setTimeout(function () {
            self._onTimeout();
    }, this._popupTimeout);
}

이것은 취소되기 전에 발사되면 거품을 보여줍니다.

MyPlan.EventPainter.prototype._onTimeout = function () {
    this._showBubble(this._futurePopup.x, this._futurePopup.y, this._futurePopup.evt);

};

MyPlan.EventPainter.prototype._showBubble = function(x, y, evt) {
    if (this._futurePopup) {
        window.clearTimeout(this._futurePopup.timeoutID);
        this._futurePopup = null;
    }        
    ...

    SimileAjax.WindowManager.cancelPopups();
    SimileAjax.Graphics.createBubbleForContentAndPoint(...);
};

이것은 이제 작동하는 것 같습니다. 나는 타임 아웃을 100ms가 아닌 200ms로 설정 한 것 같습니다. 타임 아웃이 너무 짧아서 멀티 버블 일이 발생하는 이유는 확실하지 않지만 새로 추가 된 요소가 제시되는 동안 창문 이벤트 또는 무언가가 여전히 발생할 수 있다고 생각합니다.

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