Как отложить вызов чтения потока

Я все еще пытаюсь грокнуть через streams в целом. Мне удалось передать большой файл с помощью многопартийность из form.on('part'). Но мне нужно отложить вызов и разрешить поток до его чтения. Я пробовал PassThrough, through. through2, но получили разные результаты, которые в основном зависают, и я не могу понять, что делать, ни шагов по отладке. Я открыт для всех альтернатив. Спасибо за понимание.

import multiparty from 'multiparty'
import {
  PassThrough
} from 'stream';
import through from 'through'
import through2 from 'through2'

export function promisedMultiparty(req) {
  return new Promise((resolve, reject) => {

    const form = new multiparty.Form()
    const form_files = []
    let q_str = ''

    form.on('field', (fieldname, value) => {
      if (value) q_str = appendQStr(fieldname, value, q_str)
    })

    form.on('part', async (part) => {
      if (part.filename) {

        const pass1 = new PassThrough() // this hangs at 10% 

        const pass2 = through(function write(data) { // this hangs from the beginning
            this.queue(data)
          },
          function end() {
            this.queue(null)
          })

        const pass3 = through2() // this hangs at 10%

        /* 
            // This way works for large files, but I want to defer 
            // invocation

            const form_data = new FormData()
            form_data.append(savepath, part, {
              filename,
            })

            const r = request.post(url, {
              headers: {
                'transfer-encoding': 'chunked'
              }
            }, responseCallback(resolve))
            r._form = form

        */

        form_files.push({
          part: part.pipe(pass1),
          // part: part.pipe(pass2),
          // part: part.pipe(pass3),
        })

      } else {
        part.resume()
      }
    })

    form.on('close', () => {
      resolve({
        fields: qs.parse(q_str),
        forms: form_files,
      })
    })

    form.parse(req)
  })
}

p.s. Конечно, название могло бы быть лучше, если бы кто-то мог использовать правильные термины, пожалуйста. Спасибо.

Следует отметить, что PassThrough и through2 работают с файлами меньшего размера. PassThrough и through2 ведут себя одинаково (зависает на 10%), потому что они основаны на Stream2?

garajo 13.09.2018 21:21

Не могли бы вы подробнее объяснить, чем хотите заниматься?

F.bernal 20.09.2018 14:18

Спасибо, что присмотрелся к @ F.bernal. Вместо отправки запроса из form.on('part') я хочу выполнить разрешение с помощью непрочитанного потока, а в функции, в которой выполняется обещание, начать потоковую передачу с дополнительным контекстом.

garajo 21.09.2018 11:00

В противном случае были бы полезны любые советы о том, как отлаживать или раскрывать запись потока multiparty.

garajo 21.09.2018 11:09

Поправьте меня если я ошибаюсь. Вы хотите, чтобы этот multipart выполнял свою работу, предоставляя вам фрагменты файла и точку, в которой вызывается ваша функция promiseMultiparty, и запускает потоковую передачу файлов?

F.bernal 21.09.2018 11:25

Да @ F.bernal. Спасибо за ответ

garajo 21.09.2018 16:52
10
6
262
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я считаю, что это связано с тем, что вы неправильно используете through2, то есть фактически не очищаете буфер после его заполнения (поэтому он зависает на 10% для больших файлов, но работает с меньшими).

Я считаю, что такая реализация должна это сделать:

const pass2 = through2(function(chunk, encoding, next) {

   // do something with the data


   // Use this only if you want to send the data further to another stream reader 
   // Note - From your implementation you don't seem to need it
   // this.push(data)

   // This is what tells through2 it's ready to empty the 
   //  buffer and read more data
   next();
})

Это был недостающий элемент логики. Спасибо!

garajo 10.10.2018 06:38

Другие вопросы по теме