2016-08-07 2 views
0

Я пытаюсь использовать FileReader для последовательного чтения нескольких файлов с использованием обещаний для этого. Проблема в том, что мне нужно разделить операции чтения несколькими кусками, чтобы сделать их выполнимыми. Поступая таким образом, я теряю цепочку обещаний. Это то, что происходит в следующем коде, где я получаю консольный журнал here, затем catched (что означает, что я потерял цепочку), затем inside, а затем finished. Так или иначе обещание в загрузке не соблюдается.Javascript, сплайсированный FileReader для больших файлов с обещаниями, как?

Здесь код (пожалуйста, перейдите к последнему EDIT, я сохранить исходный текст тем не менее)

var reader = new FileReader(); 
reader.onloadend = function(e) { 
    if (e.target.readyState == 2) { 
    console.log('inside') 
    start = temp_end; 
    temp_end = start + BYTES_PER_CHUNK; 
    if (temp_end > end) temp_end = end; 
    upload(); 
    } 
}; 

Array.reduce(function(promise, item) { 
    start = 0; 
    temp_end = start + BYTES_PER_CHUNK; 
    end = parseInt(totalsize); 
    if (temp_end > end) temp_end = end; 
    uploading_file = item; 
    return upload() 
    .then(function(){ 
    console.log('not shown'); 
    }) 
    .catch(console.log('catched')); 
},0); 

function upload() { 
    return new Promise(function(resolve,reject) { 
    if (start < end) { 
     console.log('here') 
     var chunk = uploading_file.slice(start, temp_end); 
     reader.readAsBinaryString(chunk); 
    } else { 
     console.log('finished') 
     uploading_file = null; 
     resolve(); 
    } 
    } 
} 

edit1: новый код, который я пытаюсь, по-прежнему console.log stop 1 появляется перед upload и here 2

 var start = 0; 
     var temp_end = start + BYTES_PER_CHUNK; 
     var end = parseInt(item.size); 
     if (temp_end > end) temp_end = end; 
     uploading_file = item; 
     console.log('here 1') 
     Promise.resolve().then(function() { 
      return upload(); 
     }) 
     .then(function(){ 
      console.log('here 2') 
     }) 
     .catch(console.log('stop 1')); 

     function upload() { 
      console.log('upload') 
      if (start < end) { 
       var chunk = uploading_file.slice(start, temp_end); 
       var reader = new FileReader(); 
       reader.readAsArrayBuffer(chunk); 
       reader.onload = function(e) { 
        if (e.target.readyState == 2) { 
         start = temp_end; 
         temp_end = start + BYTES_PER_CHUNK; 
         if (temp_end > end) temp_end = end; 
         return upload(); 
        } 
       } 
      } else { 
       console.log('finished') 
       uploading_file = null; 
       return Promise.resolve(); 
      } 
     } 

EDIT2: журналы уловов были там из-за отсутствие функции(). Следующий код, похоже, работает, но я не вижу значения content, что меня интересует в конце.

Проблема заключается в том, что обещания действительно не работают здесь, то console.log говорит

here 1 
here 2 
here 4 
here 3 

Код:

 var item; // item is a file 
     var BYTES_PER_CHUNK = 100000; 
     var start = 0; 
     var temp_end = start + BYTES_PER_CHUNK; 
     var end = parseInt(item.size); 
     if (temp_end > end) temp_end = end; 
     var content = ''; // to be filled by the content of the file 
     var uploading_file = item; 
console.log('here 1'); 
     Promise.resolve().then(function() { 
console.log('here 2'); 
      return upload(); 
     }) 
     .then(function(content){ 
console.log('here 4'); 
      console.log(content); // this is empty (!!) 
     }) 
     .catch(function(){ 
      console.log('stop 1') 
     }); 

     function upload() { 
      if (start < end) { 
       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; 
         return upload(); 
        } 
       } 
      } else { 
       uploading_file = null; 
       console.log(content); // it shows the content of the file 
console.log('here 3'); 
       return Promise.resolve(content); 
      } 
     } 
+2

Мне очень трудно понять, что вы пытаетесь сделать. У вас много незадекларированных переменных, общего состояния и неправильного кода ('Array.reduce'? Является ли' Array' фактически переменной в вашем реальном коде?). И 'upload', похоже, не имеет никакого отношения к загрузке, и возвращенное обещание иногда не разрешает или не отклоняет. Я попытаюсь угадать попытку, но если вы точно проясните, в чем заключается цель кода. – Jacob

+0

Пожалуйста, перейдите к последнему EDIT для окончательного кода. В любом случае, Array.reduce означал, что у меня был массив, и что я использовал сокращение, но эта часть кода действительно не важна для проблемы, которую я хочу изолировать. Надеюсь, что с последним кодом яснее, чего я хочу достичь? Конечная цель - прочитать файлы кусками и сохранить контроль над этим через обещания – Gerard

+0

Намного понятнее, спасибо. – Jacob

ответ

1

Ваш upload() функция не всегда возвращает обещание. Это делает условие еще, но условие if этого не делает. У вас есть оператор возврата, но он находится внутри обратного вызова , поэтому он не будет получен вызывающим абонентом upload.

Попробуйте изменить что к этому:

function upload() { 
    if (start < end) { 
    return new Promise(function (resolve, reject) { 
     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; 
    console.log(content); // it shows the content of the file 
    return Promise.resolve(content); 
    } 
} 

Теперь upload всегда возвращает обещание вместо undefined.

+0

Фантастический. Это оно. Ты спасибо! Сейчас я беспокоюсь, используя Array.reduce здесь. Поскольку это было хорошо решено, я открываю новый вопрос для этого: http://stackoverflow.com/questions/38822187/javascript-uploading-several-files-within-ar-reduce-with-promises-how , если у вас есть время – Gerard

Смежные вопросы