【问题标题】:Javascript converting to blob undefined [duplicate]Javascript转换为未定义的blob [重复]
【发布时间】:2021-08-04 08:04:57
【问题描述】:

当我尝试将画布转换为 blob 时,我的值未定义。我在下面有这段代码可以正常工作,但是当我尝试将下面的控制台日志移动到函数时,它给了我未定义的结果。

这是工作代码:

    const handleSave = (params) => {
    
    let previewUrl;
    previewCanvasRef.current.toBlob(
      (blob) => {
        previewUrl = window.URL.createObjectURL(blob);
        console.log(previewUrl);                  
      },
      'image/png',
      1
    );
}

当我尝试在下面创建控制台日志时。那么它给了我一个无敌的价值:

const handleSave = (params) => {
    
    let previewUrl;
    previewCanvasRef.current.toBlob(
      (blob) => {
        previewUrl = window.URL.createObjectURL(blob);
        
      },
      'image/png',
      1
    );

    console.log(previewUrl);
}

这是我尝试过的但错误:

const handleSave = (params) => {
    
    let previewUrl;
    previewCanvasRef.current.toBlob(
      async (blob) => {
        previewUrl = window.URL.createObjectURL(blob);        
      },
      'image/png',
      1
    ).then((res) => console.log(res));  
}

【问题讨论】:

  • 不,没有什么将它改回 undefined ...您的第二段代码在设置 previewUrl 之前记录它 - 因为 ... asyncrhony
  • toBlob 函数的第一个参数是回调。这将以异步方式工作。在第二种情况下,控制台将立即被记录(在调用回调之前),因此它将不起作用。
  • 我如何设置它的确切值?对此感到抱歉。我是 js @JaromandaX 的初学者
  • 你正在设置它...previewUrl = window.URL.createObjectURL(blob); ...你需要在回调中做任何你需要的事情
  • 在你的回调中做你的控制台。

标签: javascript ecmascript-6 es6-promise


【解决方案1】:

这是您正在寻找的将其转换为异步函数的语法:

const canvasToBlob = () => new Promise((resolve, reject) => {
  previewCanvasRef.current.toBlob(resolve, 'image/png', 1);
});

const handleSave = async () => {
  const blob = await canvasToBlob();
  const previewURL = URL.createObjectURL(blob);
}

因为async/await 只是包装 Promises 的语法糖,如果你想用传统的回调函数创建自己的 async 函数,你需要手动使用 Promises(因为你可以't returntoBlob 的回调退出canvasToBlob 函数,因为这将简单地返回toBlob 方法)。

所以,在这里,我们只是告诉toBlob 使用resolve 作为它的回调:Promise 的resolve(arg) 等价于async 函数的return arg(而reject(err) 等价于throw err) .在这种情况下,传递给toBlob 回调的Blobarg。我们现在可以将此函数与async/await 语法糖一起使用。

请记住,当您使用异步函数时,您的 整个 链需要处于 async 模式:依赖此 blob 的每个函数都需要用async/await 语法或.then'd 包装——因为同步函数不能依赖异步值。在现实世界中,这意味着你必须记住将你的函数定义为async

This page from MDN将为您提供一些关于JS中异步函数的更详细的阅读。

【讨论】:

    【解决方案2】:

    处理异步的最简单方法是使用 Promises

    const handleSave = (params) =>
      new Promise((resolve) =>
        previewCanvasRef.current.toBlob(
          (blob) => resolve(window.URL.createObjectURL(blob)),
          "image/png",
          1
        )
      );
    

    像这样使用它

    handleSave(......).then(blob => {
      // do things here
    });
    

    或使用 async/await - 必须在异步函数中才能这样做

    async function () {
      const blob = await handleSave(.....);
      // do things with blob
    }
    

    【讨论】:

    • 你好我编辑了我的问题.. 你能检查我上面的代码吗
    • @DarkVader191919- 你不能只将.then 附加到任何功能上并期望它能够工作 - 这不是编程的工作方式 - 我已经在这个答案中向你展示了如何做到这一点跨度>
    • 因为我有另一个函数要在handleSave里面执行..
    • 我只希望里面的函数有我想要的值。然后在handleSave中执行另一个函数
    • const handleSave = (params) => { return new Promise(resolve => previewCanvasRef.current.toBlob((blob) => { resolve(window.URL.createObjectURL(blob)); }, 'image/png',1); } 是错误的
    猜你喜欢
    • 2021-02-25
    • 2016-07-13
    • 2013-01-16
    • 2017-10-11
    • 1970-01-01
    • 2020-08-14
    • 2021-07-20
    • 2021-03-02
    • 2015-08-31
    相关资源
    最近更新 更多