为了账号安全,请及时绑定邮箱和手机立即绑定

使用 jszip 在前端下载大量文件

使用 jszip 在前端下载大量文件

繁星coding 2022-01-13 10:50:58
无法使用 jszip 压缩所有文件。JS zip 正在从控制台从大约 143 个请求中读取所有 402 个文件,如快照所示,但仅压缩 143 个文件。我正在使用并行限制同时干净地处理多个异步请求。我是如何获得结果中的所有 403 文件?private downloadUntouchedFiles = () => {let requestObjectInfo = [];let index = 0;this._eventEmitter.emit(Constants.LOADER_CHANGE, { show: true });this._eligibilitySubmissionInstance.getUntouchedFiles(this.state.filterObject).then((requests) => {  debugger;  if (!(!requests)) {    if (requests.length > 0) {      var zip = new JSZip();      var zipFileName = "ES_Unviewed_Files";      var promises = [];      this._eventEmitter.emit(Constants.LOADER_CHANGE, { show: true });      const downloadSubPromises = [];      let i =0;          requests.forEach((req) => {            req.Folder.Files.forEach(f => {              f.Name = this.state.initials + '_' + this.state.userId + '_' + f.Name;              console.log(f.Name);              i++;              console.log(i);              downloadSubPromises.push((submit: any) => {                JSZipUtils.getBinaryContent(f.ServerRelativeUrl, (err, data) => {                  try {                    if (err) {                      throw err;                    }在这种情况下,仅使用 JS Heap 上的 55-75MB。
查看完整描述

2 回答

?
神不在的星期二

TA贡献1963条经验 获得超6个赞

您可以使用asyncandawait使代码更易于理解并避免深度嵌套:


const ZIP_FILE_NAME = "ES_Unviewed_Files.zip"


const downloadUntouchedFiles = async () => {    

    const zip = new JSZip()

    const untouched = this._eligibilitySubmissionInstance.getUntouchedFiles(this.state.filterObject)    

    if (!untouched?.length) return


    const files = untouched.reduce((acc, { Folder: { Files } }) => 

        Files.forEach(f => acc.push({ name: `${this.state.userId}+${f.Name}`, ...f })), [])


    const downloads = files.map(({name, ServerRelativeUrl}) => 

        async () => ({ name, data: await fetchBinary(ServerRelativeUrl)}))


    const responses = await batched(downloads, Constants.DOWNLOAD_BATCH_MAX_FILE_LIMIT)


    responses.forEach(({ status, value: { name, data } }) => 

        status === 'fulfilled' && zip.file(name, data, { binary: true }))


    const content = await zip.generateInternalStream({ type: "blob" }).accumulate()

    await saveAs(content, ZIP_FILE_NAME)    

}


const fetchBinary = (file) => new Promise((resolve) => 

    JSZipUtils.getBinaryContent(url, (err, data) => err ? reject(err) : resolve(data)))


async function batched(fns, batchSize = 2) {

    const results = []    

    for(let start = 0, end = batchSize; start < fns.length; start += batchSize, end = start+batchSize) {

        const slice = fns.slice(start, end)        

        const promises = slice.map((fn) => fn())

        results.push([...await Promise.allSettled(promises)])

    }

    return results.flat()

}


查看完整回答
反对 回复 2022-01-13
?
浮云间

TA贡献1829条经验 获得超4个赞

这将起作用


private downloadUntouchedFiles = () => {

this._eventEmitter.emit(Constants.LOADER_CHANGE, { show: true });

let statusUpdatePromises = [];

this._eligibilitySubmissionInstance.getUntouchedFiles(this.state.filterObject).then((requests) => {

  if (!(!requests)) {

    if (requests.length > 0) {

      var zip = new JSZip();

      var zipFileName = "ES_Unviewed_Files";

      const downloadSubPromises = [];

      requests.forEach((req: any) => {

        req.Folder.Files.forEach((f: any) => {

          f.Name = this.state.userId + '_' + f.Name;

          downloadSubPromises.push((submit: any) => {

            JSZipUtils.getBinaryContent(`${new Constants().BASE_URL}${encodeURIComponent(f.ServerRelativeUrl).replace('%2F', '/')}`, (err, data) => {

              try {

                if (err) {

                  submit(null, true);

                } else {

                  zip.file(f.Name, data, { binary: true });

                  submit(null, true);

                }

              } catch (err) {

                this._eventEmitter.emit(Constants.LOADER_CHANGE, { show: false });

                this._loggerInstance.logException(Constants.SISCC_ES_EXCEPTIONS, {

                  Component: this._canonicalName,

                  Message: ErrorMessages.COM007,

                  UserName: !(!DataSingleton.getCurrentUser()) ? DataSingleton.getCurrentUser() : '',

                  Group: '',

                  Notes: err,

                  Source: Constants.EXCEPTION_UI_SOURCE,

                  ExceptionID: Guid.create().toString()

                } as ExceptionObject).then(() => {

                });

                submit(null, false);

              }

            });


          });

        });

        statusUpdatePromises.push((submit: any) => {

          this.setState({ requestObject: req }, () => {

            if (this.state.requestObject.Status !== Constants.ES_DOWNLOADREQUEST_STATUS) {

              this.updateESRequestStatus(Constants.ES_DOWNLOADREQUEST_STATUS).then(res => {

                submit(true);

              });

            } else {

              submit(true);

            }

          });

        });

      });

      parallelLimit(downloadSubPromises, Constants.UPLOAD_BATCH_MAX_FILE_LIMIT,

        (err: any, results: any) => {

          parallelLimit(statusUpdatePromises, Constants.UPLOAD_BATCH_MAX_FILE_LIMIT,

            (subErr: any, subResults: any) => {

              try {

                zip

                  .generateInternalStream({ type: "blob" })

                  .accumulate()

                  .then((content) => {

                    this._eventEmitter.emit(Constants.LOADER_CHANGE, { show: false });

                    saveAs(content, zipFileName + ".zip");

                  });

              }

              catch (err) {

                this._eventEmitter.emit(Constants.LOADER_CHANGE, { show: false });

                this._loggerInstance.logException(Constants.SISCC_ES_EXCEPTIONS, {

                  Component: this._canonicalName,

                  Message: ErrorMessages.COM007,

                  UserName: !(!DataSingleton.getCurrentUser()) ? DataSingleton.getCurrentUser() : '',

                  Group: '',

                  Notes: err,

                  Source: Constants.EXCEPTION_UI_SOURCE,

                  ExceptionID: Guid.create().toString()

                } as ExceptionObject).then(() => {

                });

              }

            });

        });

    }

  }

});

}


查看完整回答
反对 回复 2022-01-13
  • 2 回答
  • 0 关注
  • 556 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信