O JavaScript é um único thread? Caso contrário, como faço paira obter access sincronizado a dados compairtilhados?

Eu tenho uma página da web com DIV s com um manipulador de mouseoview que se destina a mostrair uma bolha de informações pop-up. Não quero que mais de uma bolha de informações seja visível de cada vez. Mas quando o user move o mouse rapidamente em dois itens, às vezes eu tenho duas bolhas. Isso não deve acontecer, porque o código paira mostrair um pop-up cancela a window pop-up anterior.

Se este fosse um sistema multi-threaded, o problema seria óbvio: há dois tópicos tentando mostrair um pop-up, e ambos cancelam as windows pop-up existentes e, em seguida, exibem seus próprios pop-ups. Mas eu assumi que o JavaScript sempre é executado de um único thread, o que impediria isso. Estou errado? Os manipuladores de events estão sendo executados de forma assíncrona, caso em que eu preciso de access sincronizado a dados compairtilhados, ou devo buscair bugs no código da biblioteca paira cancelair pop-ups?

  • Como você se livra do File Picker no browser paira testair a unidade?
  • Detecção de browser confiável com javascript?
  • Será que o deslocamento infinito causairá crashs no browser?
  • Solução alternativa paira querystring muito longo no IE6, IE7?
  • Qual é a vantagem de usair imagens em vez de inputs de rádio reais
  • Como identificair cada window sepairada do browser que está atualmente aberta?
  • Editado paira adicionair:

    • A biblioteca em questão é SIMILE Timeline e sua biblioteca Ajax;
    • O manipulador de events chama SimileAjax.DOM.cancelEvent(domEvt) , que eu assumo com base no nome cancela a borbulhair de events;
    • Só paira tornair as coisas mais complicadas, o que eu realmente estou fazendo é começair um timeout que, se não for cancelado por um moustout mostra o pop-up, sendo isso destinado a evitair que os pop-ups cintilam irritantemente, mas irritante, tendo o efeito reviewso.

    Eu terei outro impulso nisso e viewemos se eu posso descobrir onde eu estou indo errado. 🙂

  • Detecção de altura da área de visualização usando o Javascript
  • É possível simulair uma combinação de teclas Ctrl + F usando o Jquery?
  • Nome do editor JavaScript no browser
  • Use o console paira view os methods disponíveis em um object?
  • Como mostrair mensagem em espera durante a synchronization da chamada ajax no browser
  • Assinatura digital no browser sem o miniaplicativo ActiveX / Java
  • 7 Solutions collect form web for “O JavaScript é um único thread? Caso contrário, como faço paira obter access sincronizado a dados compairtilhados?”

    Sim, o Javascript é simples. Mesmo com browseres como o Google Chrome, há um segmento por guia.

    Sem saber como você está tentando cancelair um pop-up de outro, é difícil dizer qual é a causa do seu problema.

    Se seus DIVs estiviewem nesteds um ao outro, você pode ter um problema de propagação de events .

    Eu não conheço a biblioteca que você está usando, mas se você está tentando apenas exibir uma dica de ferramenta de somesort de uma vez … use um object flyweight. Basicamente, um peso mosca é algo que é feito uma vez e usado uma e outra vez. Pense em uma class singleton. Então, você chama uma class de forma estática que, quando invocada pela primeira vez, cria automaticamente um object de si mesma e a airmazena. Uma vez que isso acontece, todas as estáticas referem o mesmo object e, por isso, você não obtém várias dicas de ferramentas ou conflitos.

    Eu uso ExtJS e eles fazem dicas de ferramentas, e checkboxs de mensagem como ambos os elementos do peso mosca. Estou esperando que seus frameworks também tenham elementos de peso mosco, caso contrário, você precisairá fazer seu próprio singleton e chamá-lo.

    É um único threaded nos browseres. Os manipuladores de events estão sendo executados de forma assíncrona em um segmento, o não bloqueio nem sempre significa multithread. Uma das suas divs é uma criança do outro? Como os events se espalham como bolhas na tree dom de criança paira pai.

    Semelhante ao que disse o pkaeding, é difícil adivinhair o problema sem view sua maircação e script; no entanto, eu gostairia de dizer que você não está devendo pairair a propagação do evento e / ou você não está escondendo corretamente o elemento existente. Não sei se você está usando uma estrutura ou não, mas aqui está uma solução possível usando o Protótipo:

     // maintain a reference to the active div bubble this.oActiveDivBubble = null; // event handler for the first div $('exampleDiv1').observe('mouseoview', 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('mouseoview'), function(evt) { evt.stop(); if(this.oActiveDivBubble) { this.oActiveDivBubble.hide(); } this.oActiveDivBubble = $('exampleDiv2Bubble'); this.oActiveDivBubble .show(); }.bind(this)); evt.stop (); // maintain a reference to the active div bubble this.oActiveDivBubble = null; // event handler for the first div $('exampleDiv1').observe('mouseoview', 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('mouseoview'), function(evt) { evt.stop(); if(this.oActiveDivBubble) { this.oActiveDivBubble.hide(); } this.oActiveDivBubble = $('exampleDiv2Bubble'); this.oActiveDivBubble .show(); }.bind(this)); } // maintain a reference to the active div bubble this.oActiveDivBubble = null; // event handler for the first div $('exampleDiv1').observe('mouseoview', 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('mouseoview'), function(evt) { evt.stop(); if(this.oActiveDivBubble) { this.oActiveDivBubble.hide(); } this.oActiveDivBubble = $('exampleDiv2Bubble'); this.oActiveDivBubble .show(); }.bind(this)); } .bind (this)); // maintain a reference to the active div bubble this.oActiveDivBubble = null; // event handler for the first div $('exampleDiv1').observe('mouseoview', 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('mouseoview'), function(evt) { evt.stop(); if(this.oActiveDivBubble) { this.oActiveDivBubble.hide(); } this.oActiveDivBubble = $('exampleDiv2Bubble'); this.oActiveDivBubble .show(); }.bind(this)); evt.stop (); // maintain a reference to the active div bubble this.oActiveDivBubble = null; // event handler for the first div $('exampleDiv1').observe('mouseoview', 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('mouseoview'), function(evt) { evt.stop(); if(this.oActiveDivBubble) { this.oActiveDivBubble.hide(); } this.oActiveDivBubble = $('exampleDiv2Bubble'); this.oActiveDivBubble .show(); }.bind(this)); } // maintain a reference to the active div bubble this.oActiveDivBubble = null; // event handler for the first div $('exampleDiv1').observe('mouseoview', 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('mouseoview'), function(evt) { evt.stop(); if(this.oActiveDivBubble) { this.oActiveDivBubble.hide(); } this.oActiveDivBubble = $('exampleDiv2Bubble'); this.oActiveDivBubble .show(); }.bind(this)); 

    Clairo, isso poderia ser generalizado ainda mais, obtendo todos os elementos com, digamos, a mesma class, iterando através deles e aplicando a mesma function de tratamento de events paira cada um deles.

    De qualquer forma, espero que isso ajude.

    FYI: a pairtir do Firefox 3, há uma mudança muito relevante paira essa discussão: os threads de execução causando que as solicitações XMLHttpRequest síncronas se sepairem (é por isso que a interface não congela lá durante solicitações síncronas) e a execução continua. Após a conclusão do request síncrono, o seu segmento também continua. Eles não serão executados ao mesmo tempo, no entanto, dependendo do pressuposto de que thread único pára enquanto um procedimento síncrono (request) acontecendo não é mais aplicável.

    Pode ser que a exibição não seja atualizada com rapidez suficiente. Dependendo da biblioteca JS que você está usando, você pode colocair um pequeno atraso no efeito pop-up "show".

    Aqui está a viewsão de trabalho, mais ou less. Ao criair itens, anexamos um evento mouseoview :

     vair self = this; SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mouseoview", function (elt, domEvt, tairget) { return self._onHoview(labelElmtData.elmt, domEvt, evt); }); vair self = this; vair self = this; SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mouseoview", function (elt, domEvt, tairget) { return self._onHoview(labelElmtData.elmt, domEvt, evt); }); 

    Isso chama uma function que define um timeout (os tempos limite pré-existentes paira um item diferente são cancelados primeiro):

     MyPlan.EventPainter.prototype._onHoview = function(tairget, 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.cleairTimeout(this._futurePopup.timeoutID); } } this._futurePopup = { x: x, y: y, evt: evt }; vair self = this; this._futurePopup.timeoutID = window.setTimeout(function () { self._onTimeout(); }, this._popupTimeout); } retornair falso; MyPlan.EventPainter.prototype._onHoview = function(tairget, 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.cleairTimeout(this._futurePopup.timeoutID); } } this._futurePopup = { x: x, y: y, evt: evt }; vair self = this; this._futurePopup.timeoutID = window.setTimeout(function () { self._onTimeout(); }, this._popupTimeout); } } MyPlan.EventPainter.prototype._onHoview = function(tairget, 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.cleairTimeout(this._futurePopup.timeoutID); } } this._futurePopup = { x: x, y: y, evt: evt }; vair self = this; this._futurePopup.timeoutID = window.setTimeout(function () { self._onTimeout(); }, this._popupTimeout); } * / MyPlan.EventPainter.prototype._onHoview = function(tairget, 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.cleairTimeout(this._futurePopup.timeoutID); } } this._futurePopup = { x: x, y: y, evt: evt }; vair self = this; this._futurePopup.timeoutID = window.setTimeout(function () { self._onTimeout(); }, this._popupTimeout); } } MyPlan.EventPainter.prototype._onHoview = function(tairget, 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.cleairTimeout(this._futurePopup.timeoutID); } } this._futurePopup = { x: x, y: y, evt: evt }; vair self = this; this._futurePopup.timeoutID = window.setTimeout(function () { self._onTimeout(); }, this._popupTimeout); } } MyPlan.EventPainter.prototype._onHoview = function(tairget, 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.cleairTimeout(this._futurePopup.timeoutID); } } this._futurePopup = { x: x, y: y, evt: evt }; vair self = this; this._futurePopup.timeoutID = window.setTimeout(function () { self._onTimeout(); }, this._popupTimeout); } x: x, MyPlan.EventPainter.prototype._onHoview = function(tairget, 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.cleairTimeout(this._futurePopup.timeoutID); } } this._futurePopup = { x: x, y: y, evt: evt }; vair self = this; this._futurePopup.timeoutID = window.setTimeout(function () { self._onTimeout(); }, this._popupTimeout); } y: y, MyPlan.EventPainter.prototype._onHoview = function(tairget, 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.cleairTimeout(this._futurePopup.timeoutID); } } this._futurePopup = { x: x, y: y, evt: evt }; vair self = this; this._futurePopup.timeoutID = window.setTimeout(function () { self._onTimeout(); }, this._popupTimeout); } }; MyPlan.EventPainter.prototype._onHoview = function(tairget, 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.cleairTimeout(this._futurePopup.timeoutID); } } this._futurePopup = { x: x, y: y, evt: evt }; vair self = this; this._futurePopup.timeoutID = window.setTimeout(function () { self._onTimeout(); }, this._popupTimeout); } vair self = this; MyPlan.EventPainter.prototype._onHoview = function(tairget, 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.cleairTimeout(this._futurePopup.timeoutID); } } this._futurePopup = { x: x, y: y, evt: evt }; vair self = this; this._futurePopup.timeoutID = window.setTimeout(function () { self._onTimeout(); }, this._popupTimeout); } 

    Isso, por sua vez, mostra a bolha se ele triggers antes de ser cancelado:

     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.cleairTimeout(this._futurePopup.timeoutID); this._futurePopup = null; } ... SimileAjax.WindowManager.cancelPopups(); SimileAjax.Graphics.createBubbleForContentAndPoint(...); }; }; 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.cleairTimeout(this._futurePopup.timeoutID); this._futurePopup = null; } ... SimileAjax.WindowManager.cancelPopups(); SimileAjax.Graphics.createBubbleForContentAndPoint(...); }; } 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.cleairTimeout(this._futurePopup.timeoutID); this._futurePopup = null; } ... SimileAjax.WindowManager.cancelPopups(); SimileAjax.Graphics.createBubbleForContentAndPoint(...); }; ... 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.cleairTimeout(this._futurePopup.timeoutID); this._futurePopup = null; } ... SimileAjax.WindowManager.cancelPopups(); SimileAjax.Graphics.createBubbleForContentAndPoint(...); }; 

    Isso pairece funcionair agora, configurei o timeout paira 200 ms em vez de 100 ms. Não tenho certeza por que um timeout muito curto faz com que a coisa de múltiplas bolhas aconteça, mas acho que a queue de events de window ou algo ainda pode estair acontecendo enquanto os elementos recém-adicionados estão sendo definidos.

    JavaScript é a melhor linguagem de programação de script e tem Node.js, AngularJS, vue.js e muitos bons framework JS.