jszip заархивирует только один из двух файлов по URL-адресу

Я пытаюсь заархивировать два файла с URL-адреса, используя надстройку jszip, и у меня возникла небольшая проблема. Я пытаюсь заархивировать два файла с URL-адреса (в настоящее время тестируется с ссылками imgur), однако заархивируется только один из моих файлов. Я не уверен, что я делаю что-то неправильно в моей функции foreach?

Любые предложения будут потрясающими, спасибо.

function urlToPromise(url) 
{
    return new Promise(function(resolve, reject) 
    {
        JSZipUtils.getBinaryContent(url, function (err, data) 
        {
            if(err) 
            {
                reject(err);
            } else {
                resolve(data);
            }
        });
    });
}

(function () 
{
  var zip = new JSZip();
  var count = 0;
  var zipFilename = "instasamplePack.zip";
  var urls = [
    'https://i.imgur.com/blmxryl.png',
    'https://i.imgur.com/Ww8tzqd.png'
  ];

  function bindEvent(el, eventName, eventHandler) {
    if (el.addEventListener){
      // standard way
      el.addEventListener(eventName, eventHandler, false);
    } else if (el.attachEvent){
      // old IE
      el.attachEvent('on'+eventName, eventHandler);
    }
  }

  // Blob
  var blobLink = document.getElementById('kick');
  if (JSZip.support.blob) {
    function downloadWithBlob() {

      urls.forEach(function(url){
        var filename = "element" + count + ".png";
        // loading a file and add it in a zip file
        JSZipUtils.getBinaryContent(url, function (err, data) {
          if(err) {
            throw err; // or handle the error
          }
          zip.file(filename, urlToPromise(urls[count]), {binary:true});
          count++;
          if (count == urls.length) {
            zip.generateAsync({type:'blob'}).then(function(content) {
              saveAs(content, zipFilename);
            });
          }
        });
      });
    }
    bindEvent(blobLink, 'click', downloadWithBlob);
  } else {
    blobLink.innerHTML += " (not supported on this browser)";
  }

})();

person Nick Garver    schedule 18.01.2017    source источник


Ответы (1)


Когда вы делаете

urls.forEach(function(url){
  var filename = "element" + count + ".png";               // 1
  JSZipUtils.getBinaryContent(url, function (err, data) {
    count++;                                               // 2
  });
});

вы выполняете 1 два раза, а когда загрузка заканчивается, вы вызываете 2. count по-прежнему равно нулю в обоих случаях (в 1), вы перезаписываете одно изображение другим (то же имя).

Вы также загружаете каждое изображение два раза: urlToPromise уже звонит JSZipUtils.getBinaryContent.

Чтобы это исправить:

  • используйте параметр index обратного вызова forEach вместо count
  • JSZip принимает обещания (и ждет их внутри), urlToPromise уже все конвертирует: используйте его
  • не пытайтесь ждать обещаний, JSZip уже это делает

Это дает новую функцию downloadWithBlob:

function downloadWithBlob() {
  urls.forEach(function(url, index){
    var filename = "element" + index + ".png";
    zip.file(filename, urlToPromise(url), {binary:true});
  });
  zip.generateAsync({type:'blob'}).then(function(content) {
    saveAs(content, zipFilename);
  });
}
person David Duponchel    schedule 18.01.2017
comment
спасибо, ваш переписанный файл DownloadWithBlob был тем, что мне было нужно - person Ralph Dell; 09.06.2017