【问题标题】:Azure DevOps WebExtension use WebWorkerAzure DevOps WebExtension 使用 WebWorker
【发布时间】:2020-01-07 02:48:52
【问题描述】:

我想在 Azure DevOps 服务器上的 WebExtension 中使用 WebWorker

处理大型仓库的数据成本很高,所以我想在后台使用WebWorker进行计算。

但是当我打电话给new Worker("static/js/WorkerLoadTree.js"):

//CREATE WORKER
console.log("BEFORE NEW WORKER CALL")
BackgroundWorker = new Worker("static/js/WorkerLoadTree.js");
console.log("AFTER NEW WORKER CALL")

我在 Edge 中看到:

我在 Chrome 中看到了更多细节:

VSS.SDK.min.js:2 Rejected XDM promise with no reject callbacks                                                  n._reject @ VSS.SDK.min.js:2
VSS.SDK.min.js:2 DOMException: Failed to construct 'Worker': Script at 'http://136.310.18.216:8070/_apis/public/gallery/publisher/user/extension/SearchRepos/1.0.13/assetbyname/static/js/WorkerLoadTree.js' cannot be accessed from origin 'null'.
    at WorkerStart (http://136.310.18.216:8070/_apis/public/gallery/publisher/user/extension/SearchRepos/1.0.13/assetbyname/static/js/WorkerMain.js:13:32)
    at FillCode (http://136.310.18.216:8070/_apis/public/gallery/publisher/user/extension/SearchRepos/1.0.13/assetbyname/index.html:284:3)
    at http://136.310.18.216:8070/_apis/public/gallery/publisher/user/extension/SearchRepos/1.0.13/assetbyname/index.html:144:6
    at n._wrapCallback (http://136.310.18.216:8070/_apis/public/gallery/publisher/user/extension/SearchRepos/1.0.13/assetbyname/lib/VSS.SDK.min.js:2:951)
    at Array.<anonymous> (http://136.310.18.216:8070/_apis/public/gallery/publisher/user/extension/SearchRepos/1.0.13/assetbyname/lib/VSS.SDK.min.js:2:647)
    at http://136.310.18.216:8070/_apis/public/gallery/publisher/user/extension/SearchRepos/1.0.13/assetbyname/lib/VSS.SDK.min.js:2:1383            n._reject @ VSS.SDK.min.js:2
Failed to load resource: net::ERR_UNEXPECTED                                                            :8070/DefaultCollection/_apis/Contribution/HierarchyQuery/project/09737d31-b39f-49a1-8973-4a702cc4be92:1

加载WorkerLoadTree.js 似乎有问题。打电话的方式是否正确? Worker 如何访问扩展内的 js 文件?

我的扩展文件结构如下:

───SearchRepos
    │   icon.png
    │   index.html
    │   SearchRepos-1.0.14.vsix
    │   package-lock.json
    │   package.json
    │   vss-extension.json
    │
    ├───node_modules
    │   └───vss-web-extension-sdk
    │       ...
    │
    └───static
        ├───css
        │       main.css
        │
        ├───js
        │       main.js
        │       WorkerLoadCode.js <- WebWorker
        │       WorkerLoadTree.js <- WebWorker
        │       WorkerMain.js
        │
        ├───lib
        │       jquery-3.4.1.min.js
        │       jstree.js
        │
        └───themes
        ...

元:

Azure DevOps 服务器 17.143.28912.1 (AzureDevOps2019.0.1)

【问题讨论】:

    标签: javascript azure-devops


    【解决方案1】:

    DOMException:无法构造“Worker”:脚本位于 'http://136.310.18.216:8070/_apis/xxxx/static/js/WorkerLoadTree.js' 无法从源“null”访问。

    这是关于跨域访问文件的非常正常的错误。使用 web worker 有一个限制:Same Origin Policy。而且浏览器也不允许创建一个带有指向不同域的 URL 的工作者。你的调用方式导致的这个“跨域”错误是不正确的。

    BackgroundWorker = new Worker("static/js/WorkerLoadTree.js");
    

    Chrome 不允许您在从本地文件()运行脚本时加载 Web Worker,否则错误将如下所示:

    注意:我只是在我的本地机器上做一个例子。加载本地文件,即使使用相对 URL,也与使用 file: 协议加载文件相同。

    您应该使用放置这些文件的网络服务器中的 url,例如:http://xxxx:xx/static/js/WorkerLoadTree.js。或者 chrome 会将这个名为 way 的本地文件视为跨域使用文件。

    【讨论】:

    • 感谢您的回复。我能理解你写的一切,一切都是正确的。昨天我检查了这个问题并找到了这个workaround,其中 webworker 被加载为 blobnew Worker(URL.createObjectURL(new Blob(["("+worker_function.toString()+")()"], {type: 'text/javascript'})));。在本地它工作正常。 Chrome 可以执行 worker。但是作为 DevOps Webextension,我仍然得到:Rejected XDM promise with no reject callbackscode: 18, message: "SecurityError", name: "SecurityError"
    • 您是否设置了网络服务器并将文件放在那里?你用的是什么网址?
    • 作为 Webextension,Azure DevOps 自己管理将文件放到网络服务器上,还是我理解错了?
    • 不,正如您提到的,您在 TFS 服务器中上传了扩展文件。对于 TFS,它是本地服务器而不是 Web 服务器。
    • @MarTin 现在情况如何?您是否在 TFS 服务器中设置了 IIS 服务器,然后将文件放在那里?随时与我们分享您的流程,以便其他 SO 用户可以帮助您。
    【解决方案2】:

    最后我停下来遵循 WebWorker 的方法。我无法让它在 Azure DevOps WebExtension 中工作。相反,我使用 requestIdleCallback / setTimeout 方法,这在我的用例中运行良好。

    为此,您需要两个函数。

    第一:

    function TaskCaller() {
        //TASK CALLER
        TaskRunner(0, int Interations);
    }
    

    第二个:

    function TaskRunner(xCount, xEnd) {
        //TASK RUNNER
        xCount++;
    
        //ENTER CODE HERE
        console.log(xCount)
    
        //NEXT ITERATION
        if (xCount < xEnd)
            if (xCount % 1000) setTimeout(function () { TaskRunner(xCount, xEnd) }, 0);
            else TaskRunner(xCount, xEnd);
    }
    

    我意识到对于任务来说,当任务运行器每 1000 次迭代调用一次超时就足够了。当跑步者在后台计算时,我仍然可以控制页面。

    那里有更好的解决方案,例如background.js,但现在还可以。

    【讨论】:

      猜你喜欢
      • 2019-10-17
      • 2022-12-01
      • 2020-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-17
      • 2020-03-30
      • 1970-01-01
      相关资源
      最近更新 更多