Javascript,在一个数组中上载多个文件。如何减少承诺?

Javascript,在一个数组中上载多个文件。如何减少承诺?,javascript,promise,filereader,chain,array-reduce,Javascript,Promise,Filereader,Chain,Array Reduce,从演变而来,它向我展示了承诺如何也可以解析函数,现在我被困在相同的数组中。reduce函数 目标是我想上传一个数组中的文件(已经上传了),其中每个数组项(一个文件)都是按顺序上传的(即通过承诺控制) 然后,我知道答案在某种程度上是正确的,但我不明白如何将其应用到这里。我的数组不是承诺数组,而是文件数组。嗯,整个事情对我来说还是很困惑 这是我的代码,如果我能看到einconsole.log消息,它就会工作: return myArray.reduce(function(previous, curr

从演变而来,它向我展示了承诺如何也可以解析函数,现在我被困在相同的数组中。reduce函数

目标是我想上传一个数组中的文件(已经上传了),其中每个数组项(一个文件)都是按顺序上传的(即通过承诺控制)

然后,我知道答案在某种程度上是正确的,但我不明白如何将其应用到这里。我的数组不是承诺数组,而是文件数组。嗯,整个事情对我来说还是很困惑

这是我的代码,如果我能看到
ein
console.log消息,它就会工作:

return myArray.reduce(function(previous, current) {
    var BYTES_PER_CHUNK = 100000;
    var start = 0;
    var temp_end = start + BYTES_PER_CHUNK;
    var end = parseInt(current.size);
    if (temp_end > end) temp_end = end;
    var content = ''; // to be filled by the content of the file
    var uploading_file = current;
    Promise.resolve().then(function() {
        return upload();
    })
    .then(function(content){
        // do stuff with the content
        Promise.resolve();
    });
},0)  // I add the 0 in case myArray has only 1 item
//},Promise.resolve()) goes here?

.then(function(){
    console.log('ein') // this I never see
});

function upload() {
  if (start < end) {
    return new Promise(function(resolve){
      var chunk = uploading_file.slice(start, temp_end);
      var reader = new FileReader();
      reader.readAsArrayBuffer(chunk);
      reader.onload = function(e) {
        if (e.target.readyState == 2) {
          content += new TextDecoder("utf-8").decode(e.target.result);
          start = temp_end;
          temp_end = start + BYTES_PER_CHUNK;
          if (temp_end > end) temp_end = end;
          resolve(upload());
        }
      }
    });
  } else {
    uploading_file = null;
    return Promise.resolve(content);
  }
}
})); },Promise.resolve()) .然后(函数(){ console.log('ein'); });

函数上传(){ 如果(开始<结束){ 返回新承诺(函数(解析){ var chunk=上传文件.slice(开始,临时结束); var reader=new FileReader(); reader.readAsArrayBuffer(块); reader.onload=函数(e){ 如果(e.target.readyState==2){ 内容+=新的文本解码器(“utf-8”)。解码(如目标。结果); 开始=温度\结束; temp_end=开始+每个块的字节数; 如果(temp_end>end)temp_end=end; 解析(上传()); } } }); }否则{ 上传_文件=null; 返回承诺。解决(内容); } }

  • 改进的代码,似乎可以工作,也许更容易阅读

        var start, temp_end, end;
        var BYTES_PER_CHUNK = 100000;
    
        myArray.reduce(function(previous, current) {
            return previous
            .then(function() {
                start = 0;
                temp_end = start + BYTES_PER_CHUNK;
                end = parseInt(current.size);
                if (temp_end > end) temp_end = end;
                current.data = '';
    
                return upload(current)
                .then(function(){
                    // do other stuff
                    return Promise.resolve();
                });
            });
        },Promise.resolve())
        .then(function(){
          // do other stuff
        });
    
        function upload(current) {
            if (start < end) {
                return new Promise(function(resolve){
                    var chunk = current.slice(start, temp_end);
                    var reader = new FileReader();
                    reader.readAsText(chunk);
                    reader.onload = function(e) {
                        if (e.target.readyState == 2) {
                            current.data += e.target.result;
                            start = temp_end;
                            temp_end = start + BYTES_PER_CHUNK;
                            if (temp_end > end) temp_end = end;
                            resolve(upload(current));
                        }
                    }
                });
            } else {
                return Promise.resolve();
            }
        }
    
    var开始、温度结束、结束;
    var BYTES_/_CHUNK=100000;
    myArray.reduce(函数(上一个,当前){
    返回上一个
    .然后(函数(){
    开始=0;
    temp_end=开始+每个块的字节数;
    end=parseInt(当前大小);
    如果(temp_end>end)temp_end=end;
    当前数据=“”;
    返回上载(当前)
    .然后(函数(){
    //做其他事情
    返回承诺。解决();
    });
    });
    },Promise.resolve())
    .然后(函数(){
    //做其他事情
    });
    功能上传(当前){
    如果(开始<结束){
    返回新承诺(函数(解析){
    var chunk=current.slice(开始,临时结束);
    var reader=new FileReader();
    reader.readAsText(块);
    reader.onload=函数(e){
    如果(e.target.readyState==2){
    current.data+=e.target.result;
    开始=温度\结束;
    temp_end=开始+每个块的字节数;
    如果(temp_end>end)temp_end=end;
    解析(上传(当前));
    }
    }
    });
    }否则{
    返回承诺。解决();
    }
    }
    

  • 你很接近!您需要使用上一个值;这应该是一个承诺。将reduce的初始值设置为
    Promise.resolve()
    。然后在reduce函数内部,而不是
    Promise.resolve()。然后(…)
    。您应该有如下内容:

    return previous
      .then(function() { return upload(current); })
      .then(function() { /* do stuff */ });
    
    在此处返回
    非常重要。下一次调用reduce函数时,它将变成
    previous


    您在
    上传
    功能方面有很多问题。最大的问题是,您传递变量的方式使其很难读取:)(而且容易出错!)

    如果只读取文本文件,请改用
    readAsText
    。注意,我已将其重命名为
    readFile
    ,因为这是一个更准确的名称

    // returns a promise with the file contents
    function readFile(file) {
        return new Promise(function (resolve) {
            var reader = new FileReader();
            reader.onload = function(e) {
                resolve(e.target.result);
            };
            reader.readAsText(file);
        };
    }
    
    那么您的reduce就是:

    files.reduce(function(previous, file) {
        return previous
          .then(function() { return readFile(file); })
          .then(function(contents) {
              // do stuff
          });
    }, Promise.resolve());
    

    不过,
    upload\u文件
    变量有一个很大的错误。该变量是reduce函数作用域的局部变量,因此它将在
    upload
    未定义。将其作为参数传入:

    function upload(upload_file) { ... }
    

    var
    上的旁注。这就是为什么即使您在reduce函数中使用
    var
    设置
    upload\u file
    ,在调用
    upload
    函数之前,它将是什么:

    var a=3;
    函数foo(){
    var a=4;
    console.log(a);//4
    }
    foo();
    
    console.log(a);//3
    你们很接近!您需要使用上一个值;这应该是一个承诺。将reduce的初始值设置为
    Promise.resolve()
    。然后在reduce函数内部,而不是
    Promise.resolve()。然后(…)
    。您应该有如下内容:

    return previous
      .then(function() { return upload(current); })
      .then(function() { /* do stuff */ });
    
    在此处返回
    非常重要。下一次调用reduce函数时,它将变成
    previous


    您在
    上传
    功能方面有很多问题。最大的问题是,您传递变量的方式使其很难读取:)(而且容易出错!)

    如果只读取文本文件,请改用
    readAsText
    。注意,我已将其重命名为
    readFile
    ,因为这是一个更准确的名称

    // returns a promise with the file contents
    function readFile(file) {
        return new Promise(function (resolve) {
            var reader = new FileReader();
            reader.onload = function(e) {
                resolve(e.target.result);
            };
            reader.readAsText(file);
        };
    }
    
    那么您的reduce就是:

    files.reduce(function(previous, file) {
        return previous
          .then(function() { return readFile(file); })
          .then(function(contents) {
              // do stuff
          });
    }, Promise.resolve());
    

    不过,
    upload\u文件
    变量有一个很大的错误。该变量是reduce函数作用域的局部变量,因此它将在
    upload
    未定义。将其作为参数传入:

    function upload(upload_file) { ... }
    

    var
    上的旁注。这就是为什么即使您在reduce函数中使用
    var
    设置
    upload\u file
    ,在调用
    upload
    函数之前,它将是什么:

    var a=3;
    函数foo(){
    var a=4;
    console.log(a);//4
    }
    foo();
    
    console.log(a);//3
    如果你从来没有参考过前面的
    参数,那么使用Array reduce有什么意义?你基本上是在用额外的开销做一个
    forEach
    …你杀了我@T.J.Crowder-现在我需要知道链接