使用相同的模块导出到主线程js和网络工作者

问题描述 投票:0回答:1

*** 新版本*** 很难找出问题所在。现在我有了一个更好的主意:

直接导入无法反映

DOMContentLoaded
之后设置的变量,我不知道如何解决这个问题,除了向网络工作人员添加数据而不是通过导入。 即使是 main.js 模块已知的
window
,下次出现的 Web Worker(获取不同的向量层)也变得无法访问:

Error: ReferenceError: window is not defined

例如,我正在使用

window.document.baseURI
,我现在必须提供完整的 URL。

我还有一个网络工作人员,有两个步骤,第二步使用用户提供的数据(地图上的命中点)。因此模块

import
无法导入由闭包创建的函数:必须再次初始化闭包。

有什么想法吗?

*** 问题的初始版本文本(- 拼写错误)***

目前main.js使用global.js中的startTiming(),webworker.js也通过importScripts('./global.js')使用startTiming()。代码的其他一些部分位于单独的脚本文件中(例如mapmaker.js)。目前,一切正常,但这不是“模块化”,而且有点难看。

<body>
    <script src="src/mapmaker.js"></script>
    <script src="src/global.js"></script>
    <script src="src/main.js"></script>
</body>

与main.js

async function(){
    const timlog = startTiming();
    const timing = (mess) => "MAIN" + timlog(mess);
    // ...
}

global.js(简单脚本,不是模块)

function startTiming(){ /* ... performance.now initial */ }

使用 new Worker("webworker.js") 调用 webworker.js

importScripts('./global.js')
const timlog = startTiming();

我试图以导入导出的方式翻译所有内容:但我失败了。

新的main.js

import {f} from './global.js'
//instead of nothing
async function(){
//...
const context = f();
// but `export {context};` is not possible
}

新的global.js(类型=模块的脚本)

export const NAME = "name";
export function f(){ /* ... */ }

使用 new Worker("webworker.js", {type:'module'}) 调用新的 webworker.js

import {f} from './global.js'
//instead of importScripts('./global.js')
const samecontext = f();
// but `samecontext` can't be the same as `context`

我收到了一个错误(HTML 失败),该错误不是很明确。 这些修改可能还不够。 我怀疑

async
一定是顶级的,而不是在模块中。

javascript module web-worker
1个回答
0
投票

编写一个向主线程和 Web Worker 导出函数和常量的模块并不一定很困难,但这里总结了在此过程中可能出现的间接困难,以及一些解决方案。

  1. 所有脚本都是模块。

一旦脚本必须添加

import
export
指令,就必须将其翻译为模块。快速得出的结论是,所有脚本都必须直接或间接地导出和/或导入某些内容。因为它们都以某种方式为网页做出贡献。

  1. 限制 DOM
    document
    依赖代码。

启动主线程的模块(这里命名为

main.js
)必须有一个DOM接口,最好避免Web Worker直接从它导入(避免
ReferenceError: window is not defined
)。您最好添加中间模块(名为
tierWW1.js
tierWW2
...),从中导入每个
WWi
,并且其中没有 DOM 依赖项。并隔离 DOM
document
依赖代码,或使用
window

// main.js
import { morefunction } from "moremodule.js";
export { initiatedInMain };
const initiatedInMain = somevalue;
... (window independent section)...
if(typeof window !== undefined) {...(window dependent)... }

// tierWW1.js : lone intermediate with WW1
import { initiatedInMain, otherfunction } from "main.js";
export { initiatedInMain, specifTierWW };
function specificTierWW(){...}

// web worker WW1: ww1.js
import { initiatedInMain, specifTierWW } from "tierWW1.js";
self.onmessage = function(event){ ... }
  1. 在线脚本管理:

例如,如果为了懒惰的方便,您在 HTML 元素中嵌入了一个函数

.sometag. onmouseover='return popover();'> marksign </.sometag.

那么你应该在了解

window
环境的模块中拥有这个函数(或者先将其导入那里),并通过指令强制它位于顶部“窗口”:

import {popover} from "othermod.js";
window.popover = popover;

或者,不要偷懒,删除内联脚本,并通过在需要通过正确识别首先恢复的元素上编码

addEventListener()
来替换它。

  1. 全局变量通过函数调用更新。
    
    
  2. 仅导出外部更新之前获得的变量状态(
async

,或反映上下文的

object
闭包)。因此,两步网络工作者只能访问初始上下文。您必须找到一种解决方法来表示这些更改,特别是修改传达这些更改的方式。
以下是我上周开始发布最初的问题时遇到的一些障碍。可能并不详尽。

翻译工作量和投资回报率:
  1. 事实证明,如果您有一个使用 javascript 代码的网站,该代码被划分为大量脚本,并且您计划将它们翻译成模块,那么在开始该过程之前,请为“热”期做好准备。奖励?成功的自豪感。

© www.soinside.com 2019 - 2024. All rights reserved.