Hos*_*ork 8 javascript synchronization xmlhttprequest web-worker
我想要一个深入调用堆栈的Web Worker,以便能够发出同步请求以从GUI获取信息.
GUI本身没有被阻止 - 它能够处理消息.但是工作者堆栈上的JavaScript不是用async/await风格编写的.它只是很多同步代码.因此,如果GUI试图发送一个响应返回给工人用的postMessage,那也只是停留在onMessage()队列.
我发现至少有一个黑客在今天的浏览器中运行. worker可以将postMessage发送到GUI以获取它想要的信息 - 以及某种ID(例如UUID).然后,它可以将具有该ID 的同步XMLHttpRequest (在工作者上不被弃用)发布到具有该ID的Web上的某个服务器上.
当worker正在等待该http请求时,GUI处理该信息请求.完成后,它会执行XMLHttpRequest以使用ID和数据POST到同一服务器.然后,服务器使用该信息来完成它为工作人员保持打开的阻止请求.这满足了同步请求.
将GUI和工作者之间的同步外包给服务器可能看起来很难理解.但是如果必须的话,我会这样做,因为它不适合用例强制工作程序代码以异步方式编写. 此外,我假设有一天浏览器将能够本地进行这种同步.但看起来可能已使用的一种机制 - SharedArrayBuffer,暂时被禁用.
UPDATE大约2018后期: SharedArrayBuffer被重新启用在Chrome桌面V67.它还没有重新开启Android Chrome或其他浏览器,可能还需要一段时间.
(更多奇怪的选项,比如将JavaScript解释器编译到worker中,以便JS堆栈可以随意暂停和重启)不仅仅是因为大小和性能,而是使用浏览器的开发人员工具无法调试工作者.)
所以...
是否有任何方法可以将同步XMLHttpRequest愚弄,从浏览器本身发出请求(可能是通过自定义链接方案?)如果GUI线程可以直接回答可以删除中间人的XMLHttpRequest.
是否可以通过某种插件提供相同的功能?我想也许同步可以作为抽象来完成.如果有人没有插件,则会回退到使用网络作为同步代理. (并且大概如果他们重新启用SharedArrayBuffer,它可以使用它.)
我也想知道是否有某种类型的JS-ready服务已经实现了echo服务器的协议......如果有人知道一个.看起来很容易写.
我看不出有什么办法可以做你想做的事。最初看起来很有希望的方法最终会遇到难题。
fetch在评论中,您建议服务人员作为可能的解决方案。我见过的服务工作者示例提到提供“对请求的自定义响应”。但是,所有示例都使用fetch事件来提供自定义响应。fetchAFAIK,只有当您实际专门使用该API时才会产生它。xhr 不会生成 fetch 事件。(是的,我已经尝试过了,但没有成功。)并且您不能只fetch在您的具体情况下使用而不是 xhr,因为 fetch 不会同步操作。规范中fetch提到了“同步标志”,但它不是API 的一部分。
请注意,fetchAPI 和关联的事件并不特定于服务工作人员,因此您可以fetch在普通工作人员或其他地方使用(如果它解决了您的问题)。您经常会看到fetch提到服务工作线程,因为服务工作线程可用于无法使用常规工作线程的场景,并且其中一些场景需要对请求提供自定义响应fetch。
Marinos An 在评论中建议使用假 XMLHttpRequest 对象。在大多数情况下,这会起作用。像 Sinon 这样的测试框架提供了假的 XMLHttpRequest,允许测试代码完全控制被测代码获得的响应。但是,它不适用于您的用例场景。如果你的假 xhr 实现是作为一个 JavaScript 对象实现的,并且你尝试将其发送给工作程序,那么工作程序将获得它的完整克隆。在工作人员内部对假 xhr 执行的操作不会在工作人员外部看到。在工作线程外部执行的假 xhr 操作不会在工作线程内部看到。
理论上可以通过让假 xhr 由两个对象组成来解决克隆问题:一个是执行请求的前端,另一个是建立假响应的后端。您可以将前端发送给工作人员,但前端和后端必须相互通信,这会让您回到您试图解决的通信问题。如果您可以使假 xhr 的两个部分以允许伪造同步 xhr 请求的方式相互通信,那么同样,您将能够在没有假 xhr 的情况下解决通信问题。