Reactjs 在React中返回JSZip文件

Reactjs 在React中返回JSZip文件,reactjs,es6-promise,jszip,Reactjs,Es6 Promise,Jszip,我有一个函数可以压缩文件,但它会返回一个承诺。我试图实现这一点:但它仍然返回承诺,尚未解决 我对promises不太熟悉,对jsZIP也不太熟悉-如何让这个函数返回压缩文件 const getZip = (url) => { setLoadingStatus('zipping...') let zip = new JSZip(); console.log("TYPOF URL", url, typeof url) zip.fi

我有一个函数可以压缩文件,但它会返回一个承诺。我试图实现这一点:但它仍然返回承诺,尚未解决

我对promises不太熟悉,对jsZIP也不太熟悉-如何让这个函数返回压缩文件

const getZip = (url) => {
        setLoadingStatus('zipping...')
        let zip = new JSZip();
        console.log("TYPOF URL", url, typeof url)
        zip.file("Report", url)
        var promise = null;
        if (JSZip.support.uint8array) {
        promise = zip.generateAsync({type : "uint8array"}).then(content => {
            saveAs(content, "Report.zip");
          });
        } else {
        promise = zip.generateAsync({type : "string"}).then(content => {
            saveAs(content, "Report.zip");
          });
        }
        console.log("TYPEOF PROMISE", promise, typeof promise) //typeof is always promise
        return promise
    }
使用异步等待:

    async function getZip(url){
    setLoadingStatus('zipping...')
    let zip = new JSZip();
    console.log("TYPOF URL", url, typeof url)
    zip.file("Report", url)
    var content = null;
    if (JSZip.support.uint8array) {
        content = await zip.generateAsync({type : "uint8array"}).then(content => {
            saveAs(content, "Report.zip");
          })
    } else {
        content = await zip.generateAsync({type : "string"}).then(content => {
            saveAs(content, "Report.zip");
          })
    }
    return content
}
调用getZip()的函数是:


由于zip创建是异步的,因此代码处理也需要是异步的。做你的
createURL
handler异步和
wait
它内部的zip文件:

const createURL = useCallback(async (node, reportHeight, reportWidth, imgHeight) => {
    try {
        const dataUrl = await domtoimage.toJpeg(node, {width: reportInViewerRef.current.offsetWidth, height: reportInViewerRef.current.scrollHeight})
    } catch (error) {
        return console.error('oops, something went wrong!', error);
    }

    // ... you can use dataUrl from here

    let base64pdf = await getZip(btoa(fileName, pdf.output()));

    // ... do something with the zip file
}

一般来说,如果异步函数返回某些内容,那么使用它的代码也需要是异步的。

最简单的方法就是使用async/await。因此,使函数异步,然后执行类似于
let content=await-zip.generateAsync(…);saveAs(content,“Report.zip”)
然后,如果其他地方需要,您可以返回内容。您能用一个例子来充实它吗?对不起,我只是不太熟悉async,为什么你要用
reactjs
标记这个问题?我看不到任何与反应有关的东西。如果您打算在react组件内部使用此代码,但不知道如何使用,请同时添加相关代码。否则,只需删除标签。正如您调用
setLoadingStatus
一样,我猜这个函数是在组件内部使用
useState
定义的?这就是一个示例哈哈,这就是您所需要的。因此,在函数定义中,您将
async
,例如:
const getZip=async(url)…
,然后在我的第一条注释中使用该代码。您在
中拥有的“内容”。然后,
会变成等待调用的返回值,这就是为什么现在不需要
promise
变量的原因,只需将其重命名为
content
。您在哪里调用
getZip
?还请展示周围的组件。这绝对有道理-它不允许我使用回调异步tho?@Davtho1983你把
async
关键字放在哪里了?它必须直接位于箭头函数之前,而不是
useCallback
之前。这绝对有效。你不让我这么做是什么意思?有错误吗?
createURL
处理程序是否作为事件处理程序调用?我有const createURL=useCallback(异步(node,reportHeight,reportWidth,imghight)=>{…let base64pdf=wait getZip(btoa(fileName,pdf.output());…我得到的错误是解析错误:不能在异步function@Davtho1983是的,这可能就是原因。你也可以在那里使用async/await。让我更新我的答案。@Davtho1983为了保持一致,你也可以使用async/await for
toJpeg
。否则你还必须在
中生成处理程序。然后()
async。
const createURL = useCallback(async (node, reportHeight, reportWidth, imgHeight) => {
    try {
        const dataUrl = await domtoimage.toJpeg(node, {width: reportInViewerRef.current.offsetWidth, height: reportInViewerRef.current.scrollHeight})
    } catch (error) {
        return console.error('oops, something went wrong!', error);
    }

    // ... you can use dataUrl from here

    let base64pdf = await getZip(btoa(fileName, pdf.output()));

    // ... do something with the zip file
}