简体   繁体   English

无法将 object 克隆到 web worker

[英]Can not clone object to web worker

<!DOCTYPE html>
<html>

<body>
  <button type="button" onclick='UseLocalFontsButton()'>Click Me!</button>
  <script>

    async function UseLocalFontsButton() {
      try {
        const array = await self.queryLocalFonts();

        for (const font of array) {
          // blob() returns a Blob containing the bytes of the font.
          const bytes = await font.blob();
          console.log(`bytes.size = ${bytes.size}`);
          console.log(`bytes.type = ${bytes.type}`);
          // process font
        };
      } 
      catch (e) {
        console.warn(`Error: ${e.message}`);
      }
    };

</script>

</body>
</html>

Here I am getting local fonts and processing it.在这里,我正在获取本地 fonts 并对其进行处理。 It works but I need to move font processing part to worker thread.它有效,但我需要将字体处理部分移动到工作线程。 I cant move everything because queryLocalFonts only works on main thread.我无法移动所有内容,因为queryLocalFonts仅适用于主线程。

Here is my try:这是我的尝试:

<!DOCTYPE html>
<html>

<body>
  <button type="button" onclick='UseLocalFontsButton()'>Click Me!</button>

  <script>

    async function UseLocalFontsButton() {
      try {
        const array = await self.queryLocalFonts();

        let worker = new Worker('worker.js');
        worker.postMessage(JSON.stringify(array));
      } 
      catch (e) {
        console.warn(`Error: ${e.message}`);
      }
    };

</script>

</body>
</html>

And the worker:和工人:

(function () {
    onmessage = async function handleMessageFromMain(msg) 
    {
        var array = JSON.parse(msg.data);

        console.log('array = ', array);

        try {
            for (const font of array) {
                // blob() returns a Blob containing the bytes of the font.
                const bytes = await font.blob();
                console.log(`bytes.size = ${bytes.size}`);
                console.log(`bytes.type = ${bytes.type}`);
                // process font
            };
        } catch (e) {
            console.warn(`Error: ${e.message}`);
        }
    };
})();

I am getting error: Error: font.blob is not a function .我收到错误: Error: font.blob is not a function Looks like font object is not properly copied to worker thread.看起来字体 object 没有正确复制到工作线程。 Can you hint how that can be done?你能暗示如何做到这一点吗?

You don't need to serialize your data to JSON when you post it to a Worker (or other MessagePort objects for that matter);当您将数据发布到 Worker(或其他MessagePort对象)时,您不需要将数据序列化为 JSON; the postMessage() method has its own cloning algorithm able to pass many different JS object types that JSON doesn't support. postMessage()方法有自己的克隆算法,能够传递 JSON 不支持的许多不同的 JS object 类型

And while FontData is not part of these many object types, Blob is.虽然FontData不属于这些 object 类型,但Blob是。 So what you need to do is to extract all the your FontData instances as Blob and send these Blob objects to your worker.因此,您需要做的是将所有FontData实例提取为Blob ,并将这些Blob对象发送给您的工作人员。

That would give:那会给:

// main script
async function UseLocalFontsButton() {
  try {
    const fonts = await self.queryLocalFonts();
    const toTransfer = [];
    for(const font of fonts) {
      toTransfer.push({
        // You're free to add whatever other info you need
        name: font.postscriptName,
        blob: await font.blob()
      });
    }
    const worker = new Worker("worker.js");
    worker.postMessage(toTransfer);
    worker.onmessage = ({data}) => {
      log(data);
    }
  } 
  catch (e) {
    log(`Error: ${e.message}`);
  }
};
// worker script
onmessage = async ({data}) => {
  postMessage(`Received ${data.length} Blobs`);
  for(const {blob, name} of data) {
    const buf = await blob..arrayBuffer();
    // Do your analysis on the font's data
  }
};

Live example as a Glitch project since StackSnippet's don't allow access to local fonts. ( editor ).作为 Glitch 项目的实际示例,因为 StackSnippet 不允许访问本地 fonts。( 编辑)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM