2016-09-16 2 views
0

Я использую postMessage для вызова параметров для рабочего в JScript.postMessage выполняется слишком поздно в коде

Несчастливо кажется, что postMessage выполняется после того, как основной поток DOM простаивает. Мне нужна функция для публикации, когда мой код запущен.

Фон: Рабочий держит webSocket для связи с сервером.

function xy() { 
 
    flag = 0; 
 

 
    while (!flag) { 
 

 
     WORKER.postMessage(flag); 
 

 
     //Problem: WORKER does not get post; Posts are invoked after while 
 
     //Need something to break the rules 
 
     GiveWorkerExecutionTimeOrDoEventsAndMessageStack(); 
 

 
     flag := CheckFlag(); 
 
    } 
 
}

Спасибо за вашу помощь :)!

EDIT:

Я попытаюсь объяснить это ближе:

Прежде всего у меня есть рабочий, проведение веб-сокет (отдельный файл JS):

var wsUri = "ws://localhost:8002/chat"; 
 

 
var websocket; 
 

 
"use strict"; 
 

 
self.addEventListener('message', function (e) { 
 
    switch (e.data[0]) { 
 
     case "run": 
 
      runWebSocket(); 
 
      break; 
 
     case "send": 
 
      websocket.send(e.data[1]); 
 
      break; 
 
     case "addWait": 
 
      break; 
 
    } 
 
}, false); 
 

 
function runWebSocket() { 
 
    websocket = new WebSocket(wsUri); 
 
    websocket.binaryType = "arraybuffer"; 
 
    websocket.onopen = function (evt) { onOpen(evt) }; 
 
    websocket.onclose = function(evt) { onClose(evt) }; 
 
    websocket.onmessage = function(evt) { onMessage(evt) }; 
 
    websocket.onerror = function(evt) { onError(evt) }; 
 
} 
 

 
function onOpen(evt) { 
 
    self.postMessage(['open', '']); 
 
} 
 

 
function onClose(evt) { 
 
    self.postMessage(['close', '']); 
 
} 
 

 
function onMessage(evt) { 
 
    self.postMessage(['arrival', evt.data]); 
 
} 
 

 
function onError(evt) { 
 
    self.postMessage(['error', evt.data]); 
 
} 
 

 
function doSend(message) { 
 
    websocket.send(message); 
 
}

Этот рабочий работает в простой тестовой среде, в которой есть кнопка и слушатель, ожидающий нажатия События.

я получаю мое решение, если

а) отправку блока данных нажмите делается б) код ожидает получить ответ сервера, нажмите обрабатывается. Я хотел бы отпустить кнопку только в этом случае

Так что я сделал кнопку щелчка слушателя таким образом (см функцию EventCallback):

В начале я создаю ключ ожидания, который будет храниться в Карта. Пока карта содержит мой ожидающий ключ, клик не выполняется.

После публикации содержимого клика у меня есть очередь ожидания. Он должен ждать, пока мой рабочий отправит ответ, обработка должна быть выполнена.

Теперь я говорю вам список моих проблем:

1), даже если есть почта для работника (щелкните событие данных) перед ожидающей Loop, сообщение никогда не достигает работника. Работник получает сообщение после окончания цикла.

2) Я не уверен, что произойдет с моим ответом на проверку с сервера, который должен быть отправлен в основной поток. Я начал пробовать с помощью setTimeout, но если сообщение не возвращается к моему основному потоку, это вздор.

функция EventCallback (evtName) { var WaitingKey;

evtName.stopPropagation(); 

WaitingThreadCtr++; 
WaitingKey = "#" + WaitingThreadCtr; 
WaitingThreads.set(WaitingKey, WaitingKey); 

var doc = document.implementation.createDocument(null, "controlevent", null); 

// create the <submitter>, <name>, and text node 
var submitterElement = doc.createElement("command"); 
var submitterData = doc.createElement("data"); 

Att = document.createAttribute("id"); 
Att.nodeValue = 'controlEvent'; 
submitterElement.attributes.setNamedItem(Att); 

Att = document.createAttribute("threadid"); 
Att.nodeValue = WaitingKey; 
submitterElement.attributes.setNamedItem(Att); 

for (var p in evtName) { 
    Att = document.createAttribute(p); 
    Att.nodeValue = evtName[p]; 
    submitterData.attributes.setNamedItem(Att); 
} 

submitterElement.appendChild(submitterData); 
doc.documentElement.appendChild(submitterElement); 

doSend(doc.documentElement.innerHTML); 

flag = false; 
do { 
    window.setTimeout(DoInterrupt, 100); 
    if (WaitingThreads.get(WaitingKey) != WaitingKey) flag = true; 
} while (flag == false); 

}

Это лишь простой пример, потому что я хочу, чтобы этот протокол передачи данных в другом месте в моем коде для имитации функции, призывающую с ByRef параметрами.

<!DOCTYPE html> 
 
<meta charset="utf-8" /> 
 

 
<script language="javascript" type="text/javascript"> 
 

 
var wsUri = "ws://localhost:8002/chat"; 
 

 
var webSocketWorker; 
 

 
var output, outputW, outputH; 
 
var WaitingThreads; 
 
var WaitingThreadCtr; 
 
var Timer; 
 
var Interval; 
 

 
"use strict"; 
 

 
function init() { 
 
    output = document.getElementById("output"); 
 

 
    WaitingThreads = new Map(); 
 
    WaitingThreadCtr = 0; 
 

 
    webSocketWorker = new Worker("websocket.js"); 
 

 
    webSocketWorker.addEventListener('message', WebSocketServerListen, false); 
 

 
    webSocketWorker.postMessage(['run', '']); 
 
} 
 

 
function WebSocketServerListen(e) { 
 
    switch (e.data[0]) { 
 
     case 'arrival': 
 
      dataArrival(e.data[1]); 
 
      break; 
 
     case 'error': 
 
      break; 
 
     case 'open': 
 
      break; 
 
     case 'close': 
 
      break; 
 
    } 
 
} 
 

 
function doSend(message) { 
 
    webSocketWorker.postMessage(['send', message]); 
 
} 
 

 
function dataArrival(data) { 
 

 
    var i, k, m, parser, xmlDoc, NodeCommand, Tag, Att, El, id, htm, NAtt; 
 
    var DivEl, DivStyle, TagEl; 
 

 
    parser = new DOMParser(); 
 
    xmlDoc = parser.parseFromString(data, "text/xml"); 
 

 
    NodeCommand = xmlDoc.getElementsByTagName("command"); 
 

 
    //DOM ist nun verfügbar 
 
    for (i = 0; i < NodeCommand.length; i++) { 
 
     switch (NodeCommand[i].childNodes[0].textContent) { 
 
      case "event": 
 
       id = NodeCommand[i].attributes.getNamedItem("threadid").value; 
 
       WaitingThreads.delete(id); 
 
       break; 
 
      case "addControl": 
 
       //Tag einlesen; tag hat die Attribute id und html 
 
       CommandAddControl(NodeCommand[i]); 
 
       break; 
 
      case "addDiv": 
 
       //Tag einlesen; tag hat die Attribute id und html 
 
       CommandAddDiv(NodeCommand[i]); 
 
       break; 
 
      case "hideControl": 
 
       //Tag einlesen; tag hat die Attribute id und html 
 
       CommandShowHideControl(NodeCommand[i], false); 
 
       break; 
 
      case "showControl": 
 
       //Tag einlesen; tag hat die Attribute id und html 
 
       CommandShowHideControl(NodeCommand[i], true); 
 
       break; 
 
      case "resizeControl": 
 
       //Tag einlesen; tag hat die Attribute id und html 
 
       CommandResizeControl(NodeCommand[i]); 
 
       break; 
 
      case "setStyle": 
 
       //Tag einlesen; tag hat die Attribute id und html 
 
       CommandSetStyle(NodeCommand[i]); 
 
       break; 
 
      case "setProperty": 
 
       //Tag einlesen; tag hat die Attribute id und html 
 
       CommandSetProperty(NodeCommand[i]); 
 
       break; 
 
     } 
 
    } 
 
} 
 

 
function CommandAddDiv(CommandNode) { 
 
    var k, m, e, Tag, Att, El, id, htm, NAtt; 
 
    var DivEl, DivStyle, TagEl, Dest, DivDest; 
 

 
    Tag = CommandNode.getElementsByTagName("tag"); 
 

 
    for (k = 0; k < Tag.length; k++) { 
 

 
     if (Tag[k].childNodes[0]) { 
 
      El = Tag[k].childNodes[0].textContent; 
 
     } 
 

 
     id = Tag[k].attributes.getNamedItem("id").value; 
 

 
     DivEl = document.getElementById(id); 
 
     if (DivEl) DivEl.parentNode.removeChild(DivEl); 
 

 
     //div anlegen 
 
     DivEl = document.createElement("div"); 
 
     DivEl.Control = new Control(); 
 

 
     Att = document.createAttribute("id"); 
 
     Att.nodeValue = id; 
 
     DivEl.attributes.setNamedItem(Att); 
 

 
     Att = document.createAttribute("class"); 
 
     Att.nodeValue = Tag[k].attributes.getNamedItem("class").value; 
 
     DivEl.attributes.setNamedItem(Att); 
 

 
     Att = document.createAttribute("style"); 
 
     Att.nodeValue = Tag[k].attributes.getNamedItem("style").value; 
 
     DivEl.attributes.setNamedItem(Att); 
 

 
     if (Tag[k].attributes.getNamedItem("visible").value == "0") { 
 
      DivEl.style.display = "none"; 
 
     } 
 

 
     El = Tag[k].getElementsByTagName("evt"); 
 
     for (e = 0; e < El.length; e++) { 
 
      //Events binden 
 
      DivEl.addEventListener(El[e].attributes.getNamedItem("name").value, EventCallback, false); 
 
     } 
 

 
     //append to id dest 
 
     Dest = Tag[k].attributes.getNamedItem("dest").value; 
 
     if (Dest == '<root>') { 
 
      output.appendChild(DivEl); 
 
     } else { 
 
      DivDest = document.getElementById(Dest); 
 
      DivDest.appendChild(DivEl); 
 
     } 
 
    } 
 
} 
 

 
function Control() { 
 
    this.AlignLeft = 0; 
 
    this.AlignRight = 0; 
 
    this.AlignTop = 0; 
 
    this.AlignBottom = 0; 
 
} 
 

 
function CommandAddControl(CommandNode) { 
 
    var k, m, e, Tag, Att, El, id, htm, NAtt; 
 
    var DivEl, DivStyle, TagEl, Dest, DivDest; 
 

 
    Tag = CommandNode.getElementsByTagName("tag"); 
 

 
    for (k = 0; k < Tag.length; k++) { 
 

 
     if (Tag[k].childNodes[0]) { 
 
      El = Tag[k].childNodes[0].textContent; 
 
     } 
 

 
     id = Tag[k].attributes.getNamedItem("id").value; 
 

 
     DivEl = document.getElementById(id); 
 
     if (DivEl) DivEl.parentNode.removeChild(DivEl); 
 

 
     //div anlegen 
 
     DivEl = document.createElement("div"); 
 

 
     Att = document.createAttribute("id"); 
 
     Att.nodeValue = id; 
 
     DivEl.attributes.setNamedItem(Att); 
 

 
     Att = document.createAttribute("style"); 
 
     Att.nodeValue = Tag[k].attributes.getNamedItem("style").value; 
 
     DivEl.attributes.setNamedItem(Att); 
 

 
     TagEl = document.createElement(El); 
 
     TagEl.textContent = Tag[k].attributes.getNamedItem("html").value; 
 

 
     //Tag-Node kann Att-Knoten haben 
 
     NAtt = Tag[k].getElementsByTagName("att"); 
 

 
     for (m = 0; m < NAtt.length; m++) { 
 
      Att = document.createAttribute(NAtt[m].attributes.getNamedItem("name").value); 
 
      Att.nodeValue = NAtt[m].attributes.getNamedItem("value").value; 
 
      TagEl.attributes.setNamedItem(Att); 
 
     } 
 
     DivEl.appendChild(TagEl); 
 

 
     //Events binden 
 
     El = Tag[k].getElementsByTagName("evt"); 
 
     for (e = 0; e < El.length; e++) { 
 
      //Events binden 
 
      TagEl.addEventListener(El[e].attributes.getNamedItem("name").value, EventCallback, false); 
 
     } 
 

 
     //append to id dest 
 
     Dest = Tag[k].attributes.getNamedItem("dest").value; 
 
     if (Dest == '<root>') { 
 
      output.appendChild(DivEl); 
 
     } else { 
 
      DivDest = document.getElementById(Dest); 
 
      DivDest.appendChild(DivEl); 
 
     } 
 
    } 
 
} 
 

 
function CommandShowHideControl(CommandNode, ShowHide) { 
 
    var k, m, Tag, Att, El, id, htm, NAtt; 
 
    var DivEl, DivStyle, TagEl, Dest, DivDest; 
 

 
    Tag = CommandNode.getElementsByTagName("tag"); 
 

 
    for (k = 0; k < Tag.length; k++) { 
 
     id = Tag[k].attributes.getNamedItem("id").value; 
 

 
     El = document.getElementById(id); 
 
     if (El) { 
 
      if (ShowHide == false) { 
 
       El.style.display = "none"; 
 
      } else { 
 
       El.style.display = "block"; 
 
      } 
 
     } 
 
    } 
 
} 
 

 
function CommandResizeControl(CommandNode) { 
 
    var k, m, Tag, Att, El, id, htm, NAtt; 
 
    var DivEl, DivStyle, TagEl, Dest, DivDest; 
 

 
    Tag = CommandNode.getElementsByTagName("tag"); 
 

 
    for (k = 0; k < Tag.length; k++) { 
 
     id = Tag[k].attributes.getNamedItem("id").value; 
 

 
     El = document.getElementById(id); 
 
     if (El) { 
 
      El.style.left = Tag[k].attributes.getNamedItem("left").value; 
 
      El.style.top = Tag[k].attributes.getNamedItem("top").value; 
 
      El.style.width = Tag[k].attributes.getNamedItem("width").value; 
 
      El.style.height = Tag[k].attributes.getNamedItem("height").value; 
 
     } 
 
    } 
 
} 
 

 
function CommandSetStyle(CommandNode) { 
 
    var k, m, Tag, Att, El, id, htm, NAtt; 
 
    var DivEl, DivStyle, TagEl, Dest, DivDest; 
 

 
    Tag = CommandNode.getElementsByTagName("tag"); 
 

 
    for (k = 0; k < Tag.length; k++) { 
 
     id = Tag[k].attributes.getNamedItem("id").value; 
 

 
     El = document.getElementById(id); 
 
     if (El) { 
 
      El.style = Tag[k].attributes.getNamedItem("style").value; 
 
     } 
 
    } 
 
} 
 

 
function CommandSetProperty(CommandNode) { 
 
    var k, m, Tag, Att, El, id, htm, NAtt; 
 
    var DivEl, DivStyle, TagEl, Dest, DivDest; 
 

 
    Tag = CommandNode.getElementsByTagName("tag"); 
 

 
    for (k = 0; k < Tag.length; k++) { 
 
     id = Tag[k].attributes.getNamedItem("id").value; 
 

 
     El = document.getElementById(id); 
 
     if (El) { 
 
      eval("El." + Tag[k].attributes.getNamedItem("property").value + " = " + Tag[k].attributes.getNamedItem("value").value); 
 
     } 
 
    } 
 
} 
 

 
function TimeoutFunc() { 
 
    //Timer = setTimeout(TimeoutFunc, 50); 
 
} 
 

 
function WaitInterval() { 
 
    Timer = setTimeout(TimeoutFunc, 10); 
 
} 
 

 
function EventCallback(evtName) { 
 
    var WaitingKey; 
 

 
    evtName.stopPropagation(); 
 

 
    WaitingThreadCtr++; 
 
    WaitingKey = "#" + WaitingThreadCtr; 
 
    WaitingThreads.set(WaitingKey, WaitingKey); 
 

 
    var doc = document.implementation.createDocument(null, "controlevent", null); 
 

 
    // create the <submitter>, <name>, and text node 
 
    var submitterElement = doc.createElement("command"); 
 
    var submitterData = doc.createElement("data"); 
 

 
    Att = document.createAttribute("id"); 
 
    Att.nodeValue = 'controlEvent'; 
 
    submitterElement.attributes.setNamedItem(Att); 
 

 
    Att = document.createAttribute("threadid"); 
 
    Att.nodeValue = WaitingKey; 
 
    submitterElement.attributes.setNamedItem(Att); 
 

 
    for (var p in evtName) { 
 
     Att = document.createAttribute(p); 
 
     Att.nodeValue = evtName[p]; 
 
     submitterData.attributes.setNamedItem(Att); 
 
    } 
 

 
    submitterElement.appendChild(submitterData); 
 
    doc.documentElement.appendChild(submitterElement); 
 

 
    doSend(doc.documentElement.innerHTML); 
 
    
 
    flag = false; 
 
    do { 
 
     window.setTimeout(DoInterrupt, 100); 
 
     if (WaitingThreads.get(WaitingKey) != WaitingKey) flag = true; 
 
    } while (flag == false); 
 
} 
 

 
function DoInterrupt() { 
 
    
 
} 
 

 
function WindowResize(evtName) { 
 
    var w, h; 
 
    w = output.clientWidth; 
 
    h = output.clientHeight; 
 
    
 
    if ((outputW != w) || (outputH != h)) { 
 

 
     outputW = w; 
 
     outputH = h; 
 

 
     var Att; 
 
     var doc = document.implementation.createDocument(null, "windowResize", null); 
 

 
     // create the <submitter>, <name>, and text node 
 
     var submitterElement = doc.createElement("command"); 
 
     Att = document.createAttribute("id"); 
 
     Att.nodeValue = 'windowResize'; 
 
     submitterElement.attributes.setNamedItem(Att); 
 

 
     Att = document.createAttribute("width"); 
 
     Att.nodeValue = w; 
 
     submitterElement.attributes.setNamedItem(Att); 
 

 
     Att = document.createAttribute("height"); 
 
     Att.nodeValue = h; 
 
     submitterElement.attributes.setNamedItem(Att); 
 

 
     doc.documentElement.appendChild(submitterElement); 
 

 
     doSend(doc.documentElement.innerHTML); 
 

 
    } 
 
} 
 

 
function writeToScreen(message) { 
 
    var pre = document.createElement("p"); 
 
    pre.style.wordWrap = "break-word"; 
 
    pre.innerHTML = message; 
 
    output.appendChild(pre); 
 
} 
 

 
window.addEventListener("load", init, false); 
 
window.addEventListener("resize", WindowResize, false); 
 

 
</script> 
 

 
<link rel="stylesheet" href="w3.css"> 
 
<html> 
 

 
<head> 
 
<title>WebSocket Test</title> 
 
</head> 
 

 
<body> 
 
<h2>WebSocket Test</h2> 
 

 
<div id="output"></div> 
 

 
</body> 
 
</html>

+0

вы можете предоставить более подробную информацию и как вы получать сообщения в основном потоке –

+0

Все, что я могу вам сказать, что это будет работать в обычном javascript. Я просто проверил это ... –

ответ

0

Как я работал на многопоточность JS API (OODK-JS) Я мог бы ответить на этот вопрос:

не удается разорвать бесконечный цикл с вызовом асинхронной (включая setTimout), поскольку функция обратного вызова выполняется только после того, как поток будет бесплатным. Запуск бесконечный цикл монополизировать нить и все асинхронной обратного вызова задерживается до тех пор, цикл не будет сделано, который никогда не происходило

flag = false; 
do { 
    // DoInterrupt is never called as the do/while loop is monopolizing the current thread 
    window.setTimeout(DoInterrupt, 100); 
    if (WaitingThreads.get(WaitingKey) != WaitingKey) flag = true; 
} while (flag == false); 
Смежные вопросы