Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在循环所有文件后创建zip文件?_Javascript_For Loop_Xmlhttprequest - Fatal编程技术网

Javascript 如何在循环所有文件后创建zip文件?

Javascript 如何在循环所有文件后创建zip文件?,javascript,for-loop,xmlhttprequest,Javascript,For Loop,Xmlhttprequest,我正在使用JSzip创建包含所有图像文件的zipfile。我使用XMLHttpRequest从循环中的外部链接获取图像。根据我的代码,在完成XMLHttpRequest之前创建zipfile。所以它返回空的zip文件。如何在循环所有文件后创建zip文件 $(document).on('click', '.download', function(){ var path = $(this).attr("data-id"); var count = $(this).attr("val

我正在使用JSzip创建包含所有图像文件的zipfile。我使用XMLHttpRequest从循环中的外部链接获取图像。根据我的代码,在完成XMLHttpRequest之前创建zipfile。所以它返回空的zip文件。如何在循环所有文件后创建zip文件

$(document).on('click', '.download', function(){ 
    var path = $(this).attr("data-id");
    var count = $(this).attr("value");
    var storageRef = firebase.storage().ref();
    var zip = new JSZip();
    console.log(count);

    for (i = 1; i <= count; i++) { 
        console.log(path+i+".png");
        var imagePath = path+i+".png";

        // Create a reference to the file we want to download
        var starsRef = storageRef.child(imagePath);

        starsRef.getDownloadURL().then(function(url) {
        // Insert url into an <img> tag to "download"
        ImageUrl = url;

        var xhr = new XMLHttpRequest();
        xhr.open('GET', ImageUrl, true);
        xhr.responseType = "arraybuffer";
        xhr.onreadystatechange = function(evt) {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {

                    zip.file(i+".png", xhr.response);

                }
            }
        };
        xhr.send();
      })
    }
    zip.generateAsync({type:"blob"})
    .then(function(content) {
        // see FileSaver.js
        saveAs(content, "my.zip");
    });
});
$(文档).on('click','download',function(){
var path=$(this.attr(“数据id”);
var count=$(this.attr(“value”);
var storageRef=firebase.storage().ref();
var zip=newjszip();
控制台日志(计数);

对于(i=1;iJSZip支持承诺作为内容:您可以将每个HTTP调用包装成承诺,而不是显式地等待

第一个函数
downloadUrlAsPromise
将xhr调用包装成一个承诺。第二个函数
downloadFirebaseImage
getDownloadURL
的承诺与第一个函数的承诺链接起来。结果是xhr内容的承诺

一旦你做到了这一点,你就可以直接向JSZip承诺如下:

zip.file(i+".png", downloadFirebaseImage(imagePath));
完整方法:

function downloadUrlAsPromise (url) {
  return new Promise(function (resolve, reject) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = "arraybuffer";
    xhr.onreadystatechange = function(evt) {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          resolve(xhr.response);
        } else {
          reject(new Error("Ajax error for " + url + ": " + xhr.status));
        }
      }
    });
    xhr.send();
  });
}

function downloadFirebaseImage(storageRef, path) {
  var starsRef = storageRef.child(imagePath);
  return starsRef.getDownloadURL().then(function(url) {
    return downloadUrlAsPromise(url);
  });
}


// ...
for (i = 1; i <= count; i++) { 
  console.log(path+i+".png");
  var imagePath = path+i+".png";
  zip.file(i+".png", downloadFirebaseImage(imagePath));
}

zip.generateAsync({type:"blob"})
.then(function(content) {
  // see FileSaver.js
  saveAs(content, "my.zip");
});
函数下载urlaspromise(url){
返回新承诺(功能(解决、拒绝){
var xhr=new XMLHttpRequest();
xhr.open('GET',url,true);
xhr.responseType=“arraybuffer”;
xhr.onreadystatechange=函数(evt){
if(xhr.readyState==4){
如果(xhr.status==200){
解析(xhr.response);
}否则{
拒绝(新错误(“+url+”:“+xhr.status”)的Ajax错误);
}
}
});
xhr.send();
});
}
函数下载FireBaseImage(storageRef,路径){
var starsRef=storageRef.child(imagePath);
返回starsRef.getDownloadURL().then(函数(url){
返回下载url地址(url);
});
}
// ...

对于(i=1;我似乎您在循环完成之前调用了
zip.generateAsync
,因此它可以在您第一次调用
zip.file(i+“.png”,xhr.response)”之前执行;
。我假设如果您将循环包装成
promise
,您可以根据需要链接
zip.generateAsync
。这可能会有所帮助► 是的。正如我在问题中所说的,这就是问题所在。问题是我不知道如何克服这种情况。我认为这比ajax请求更难实现。除了@Fran的注释外,使用一些关键字如搜索SO会给出很多结果。@Bandara我链接了一篇SO帖子,展示了如何使用承诺。这会告诉你如何克服这个问题。效果很好。谢谢。