【问题标题】:"Uncaught ReferenceError: window is not defined" p5.js web worker“未捕获的 ReferenceError:未定义窗口”p5.js 网络工作者
【发布时间】:2021-07-12 18:30:12
【问题描述】:

我有一个 javascript 代码,我在其中使用带有 p5.js 库的网络工作者。它不允许我使用 p5 的任何函数,所以在使用 p5 的任何函数之前,我必须使用importScripts("p5.js") 函数导入 p5.js 库。

onmessage = (e)=>{
    importScripts("p5.min.js")
    // other scripts
}

但即便如此,它还是给了我另一个错误,说 “未捕获的 ReferenceError:未定义窗口”。我追踪了它,似乎 p5 无法使用名为“window”的全局变量。我在互联网上搜索了解决方案,但到目前为止还没有找到。我想知道是否有办法解决这个问题。谢谢。

【问题讨论】:

    标签: javascript multithreading p5.js web-worker


    【解决方案1】:

    这里的问题是网络工作者在一个非常孤立的环境中运行,其中许多标准全局变量对于在网站上运行的 javascript(窗口、文档等)存在,不幸的是 p5.js 不能加载没有这些变量。您可以尝试用假版本填充它们。这是一个基本示例:

    let loadHandlers = [];
    
    window = {
      performance: performance,
      document: {
        hasFocus: () => true,
        createElementNS: (ns, elem) => {
          console.warn(`p5.js tryied to created a DOM element '${ns}:${elem}`);
          // Web Workers don't have a DOM
          return {};
        }
      },
      screen: {},
      addEventListener: (e, handler) => {
        if (e === "load") {
          loadHandlers.push(handler);
        } else {
          console.warn(`p5.js tried to added an event listener for '${e}'`);
        }
      },
      removeEventListener: () => {},
      location: {
        href: "about:blank",
        origin: "null",
        protocol: "about:",
        host: "",
        hostname: "",
        port: "",
        pathname: "blank",
        search: "",
        hash: ""
      }
    };
    
    document = window.document;
    screen = window.screen;
    
    // Without a setup function p5.js will not declare global functions
    window.setup = () => {
      window.noCanvas();
      window.noLoop();
    };
    
    importScripts("/p5.js");
    
    // Initialize p5.js
    for (const handler of loadHandlers) {
      handler();
    }
    
    postMessage({ color: "green" });
    
    onmessage = msg => {
      if (msg.data === "getRandomColor") {
        // p5.js places all of its global declarations on window
        postMessage({
          color: window.random([
            "red",
            "limegreen",
            "blue",
            "magenta",
            "yellow",
            "cyan"
          ])
        });
      }
    };
    

    这仅适用于 p5.js 函数的有限子集。任何绘制到画布上的函数肯定都不起作用。我会谨慎尝试来回传递对象(即 p5.Vector、p5.Color 等),因为通过 postMessage 发送的所有内容都会被序列化和反序列化。

    我已经发布了这个例子的工作版本on Glitch

    【讨论】:

    • 它的工作原理谢谢!我仍然需要添加 const p5 = window.p5 以使其与我的 new p5.Vector() 函数一起使用。非常感谢!
    猜你喜欢
    • 2013-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-21
    • 1970-01-01
    • 2020-07-14
    • 2023-01-23
    • 2014-02-21
    相关资源
    最近更新 更多