2016-09-16 17 views
0

postMessageを使用してJScriptのワーカーにパラメータを呼び出しています。postMessageがコードで遅すぎると実行される

DOMのメインスレッドがアイドル状態になった後、残念ながらpostMessageが実行されているようです。コードが実行されている間に投稿する関数が必要です。

背景:Workerは、サーバーと通信するために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:

私は近いそれを説明してみましょう:私は、Webソケット(別の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); 
 
}

このワーカーは、クリックイベントを待機しているボタンとリスナーを持つ単純なテスト環境で実行されています。クリックデータブロックの送信

a)は b)のコードが処理されてクリックし、サーバーの答えを受け取るために待機している行われている場合、私は私の解決策を得る

、。私は(関数EventCallbackを参照)のみ

は、だから私はこのようにボタンクリックリスナーを行った。この場合、ボタンを離したい:私は内に格納される待機キーを作成開始時に

地図。マップには待機中のキーが含まれている限り、クリックはコミットされません。

クリックコンテンツを投稿した後、私は待っているループがあります。私の労働者が答えを送っている間待つべきです、処理はコミットされるべきです。

今、私はあなたに私の問題のリストを教えて:

1)労働者へのポストがあっても(メッセージは労働者に届くことはありません、待っているループの前に)イベントデータをクリックしてください。作業者は、ループを終了した後に投稿を取得します。

2)私は、メインスレッドに投稿する必要があるサーバーからの私の小切手解答で何が起こるかわかりません。私はsetTimeoutで試し始めましたが、ポストがメインスレッドに戻ってこない場合、これはナンセンスです。

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); 

}

私は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); 
関連する問題