Как я могу использовать Ax ios, чтобы получить массив файлов для передачи в Pizzip для создания архива .zip? - PullRequest
1 голос
/ 03 апреля 2020

Вот документация для Pizzip для незнакомых людей: https://github.com/open-xml-templating/pizzip/tree/master/documentation

Также я использую VueJS (2), ES6, TS

I я пытаюсь загрузить отдельные файлы с помощью Ax ios и затем поместить их в zip-файл с помощью Pizzip.

async getFile(mat: Material): Promise<any> {
    try {
      const file = await axios.get(mat.url, { responseType: 'arraybuffer' })
      return file.data
    } catch (error) {
      console.log(error)
      return {}
    }
}

Это дает мне ArrayBuffer правильно. Тогда у меня есть следующее:

async getZip() {
    let zip = new pizzip()
    this.materials.forEach(async mat => {
        const record = await PortalService.getFile(mat)
        console.log(record) // logs the ArrayBuffer
        zip.file(mat.name, record)
    })
    let files = zip.generate({ type: 'blob' })
    return saveAs(files, `${this.request.id}-files.zip`)
}

Документы Pizzip сказали, что аргумент data для zip.file() может иметь тип ArrayBuffer, но когда я загружаю zip, это просто пустой архив. Я попытался использовать необязательный параметр options для zip.file(), но ничего не помогло. Заранее спасибо.

1 Ответ

1 голос
/ 03 апреля 2020

Проблема, вероятно, связана с асин c для-l oop. Метод forEach не поддерживает функции asyn c l oop; он просто выполнит каждую итерацию, не дожидаясь, пока предыдущий завершится sh Таким образом, в основном вы генерируете zip-файл до того, как к нему были добавлены какие-либо файлы.

Есть два способа справиться с этим:

  1. Одновременно запускать все запросы и ждать их все до фини sh. Это будет быстрее, поскольку он отправляет запросы одновременно, но будьте осторожны, чтобы не спамить сотни запросов одновременно!
await Promise.all(this.materials.map(async mat => {
  const record = await PortalService.getFile(mat)
  zip.file(mat.name, record)
}))
Выполнять каждый запрос последовательно, по одному за раз. Медленнее, но не спам-запросы.
for (const mat of this.materials) {
  const record = await PortalService.getFile(mat)
  zip.file(mat.name, record)
}
...