Javascript,使用Promises在Array.reduce中上载多个文件,怎么办? [英] Javascript, uploading several files within an Array.reduce with Promises, how?

查看:96
本文介绍了Javascript,使用Promises在Array.reduce中上载多个文件,怎么办?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

演变而来,怎么办?,它向我展示了Promise也可以解析函数的方法,现在我被困在Array.reduce函数中.

Evolving from Javascript, spliced FileReader for large files with Promises, how?, which showed me how a Promise can also resolve a function, now I am stuck with the same but inside an Array.reduce function.

我的目标是我要在一个数组中上传一个文件(已经这样做了),其中每个数组项(一个文件)都按顺序上传(即通过Promise控制).

The goal is that I want to upload a file (which already does) within an array, where each array item (a file) is uploaded sequentially (i.e. controlled through promises).

然后,我了解答案是 http://www.html5rocks.com/zh-CN/tutorials/es6/promises/?redirect_from_locale=es ,但我不明白如何将其应用于此处.我的数组不是promise的数组,而是文件的数组.好吧,整个事情仍然让我感到困惑.

Then, I understand that the answer is somehow in http://www.html5rocks.com/en/tutorials/es6/promises/?redirect_from_locale=es , but I cannot understand how to apply that to here. My array is not an array of promises, is an array of files. Well, the whole thing is still obfuscated to me.

这是我的代码,如果我能看到ein console.log消息,它将起作用:

This is my code, which would work if I could see the ein console.log message:

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);
  }
}

  • 在几条评论后进行了更新,看来现在可以使用了...不确定

    • updated after several comments, it seems that now it works ... not sure yet

      var uploading_file,开始,temp_end,结束,内容; var BYTES_PER_CHUNK = 100000;

      var uploading_file, start, temp_end, end, content; var BYTES_PER_CHUNK = 100000;

      myArray.reduce(function(previous,current){ 返回上一个 .then(function(){ BYTES_PER_CHUNK = 100000; 开始= 0; temp_end =开始+ BYTES_PER_CHUNK; 结束= parseInt(current.size); 如果(temp_end> end)temp_end = end; 内容=''; uploading_file =当前;

      myArray.reduce(function(previous, current) { return previous .then(function() { BYTES_PER_CHUNK = 100000; start = 0; temp_end = start + BYTES_PER_CHUNK; end = parseInt(current.size); if (temp_end > end) temp_end = end; content = ''; uploading_file = current;

      upload()
      .then(function(content){
          // do stuff with "content"
          console.log('here')
          return Promise.resolve();
      });
      

      }); },Promise.resolve()) .then(function(){ console.log('ein'); });

      }); },Promise.resolve()) .then(function(){ console.log('ein'); });

      function upload(){ 如果(开始<结束){ 返回新的Promise(function(resolve){ var chunk = uploading_file.slice(start,temp_end); var reader = new FileReader(); reader.readAsArrayBuffer(chunk); reader.onload = function(e){ 如果(e.target.readyState == 2){ 内容+ =新的TextDecoder("utf-8").decode(e.target.result); 开始= temp_end; temp_end =开始+ BYTES_PER_CHUNK; 如果(temp_end> end)temp_end = end; resolve(upload()); } } }); } 别的 { uploading_file = null; 返回Promise.resolve(content); } }

      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); } }

      经过改进的代码似乎可以正常工作,也许更容易阅读?

      improved code, seems to work, perhaps easier to read?

          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();
              }
          }
      

    • 推荐答案

      您非常亲密!您需要使用先前的值;这应该是一个承诺.将reduce的初始值设置为Promise.resolve().然后在reduce函数内部,而不是Promise.resolve().then(...).你应该有这样的东西:

      You're very close! You need to use the previous value; it should be a promise. Set the initial value of the reduce to be Promise.resolve(). Then inside the reduce function, instead of Promise.resolve().then(...). you should have something like:

      return previous
        .then(function() { return upload(current); })
        .then(function() { /* do stuff */ });
      

      在这里return很重要.下次调用reduce函数时,它将变为previous.

      It's important that you return here. This will become previous next time the reduce function is called.

      upload函数存在很多问题. 最大问题是,您传递变量的方式使其很难阅读:)(而且容易出错!)

      You have quite a few issues with the upload function. The biggest issue is that the way you are passing it variables makes it very hard to read :) (and error-prone!)

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

      If you're only reading a text file, use readAsText instead. Note I've renamed it to readFile, because that's a more accurate name.

      // 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);
          };
      }
      

      那么您的减少就是:

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


      尽管您使用upload_file变量遇到了一个大错误.该变量在reduce函数作用域内是局部变量,因此它将位于upload内的undefined之外.而是将其作为参数传递:


      You have a big bug with the upload_file variable though. The variable is local to the scope of the reduce function, so it will but undefined inside upload. Pass that in as an argument instead:

      function upload(upload_file) { ... }
      


      var的旁注.这就是为什么即使在reduce函数中将upload_filevar一起设置的原因,也仍然是在为upload调用该函数之前的情况:


      Side note on var. This is why even though you set upload_file with var inside the reduce function, it would be whatever it was before that function was called for upload:

      var a = 3;
      
      function foo() {
        var a = 4;
        console.log(a); // 4
      }
      
      foo();
      console.log(a); // 3

      这篇关于Javascript,使用Promises在Array.reduce中上载多个文件,怎么办?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆