Javascript 转换为 blob undefined

Javascript converting to blob undefined

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

这是工作代码:

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

当我尝试在下面创建控制台日志时。然后它给了我一个 undefiend 值:

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));  
}

处理异步最简单的方法是使用 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
}

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

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 只是包装 Promise 的语法糖,如果你想从传统的回调函数中创建你自己的 async 函数,你需要手动使用 Promises(因为您不能 return toBlob 的回调中退出 canvasToBlob 函数,因为那样只会 return 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异步函数阅读