有一个busboy library。使用一些promise库,我可以使用以下代码将整个表单数据收集到一个对象中:

var p = new Promise((resolve) => {
  let res = {}
  busboy.on('file', (fieldname, file, filename, encoding, mimetype)=> {
    let name = uuid.v1()
    let extension = path.extname(filename)
    let saveTo = path.resolve(mediaPath, `${name}${extension}`)
    file.pipe(fs.createWriteStream(saveTo))
    res = _.extend(res, {
      [fieldname]: { filename }
    })
  })
  busboy.on('field', (key, value, keyTruncated, valueTruncated) => {
    res = _.extend({[key]: value})
  })
  busboy.on('finish', () => resolve(res))
})
p.then((data) => ...


它可以工作,但看起来有点像意大利面条。有没有办法使用RxJS改进此示例?

最佳答案

我可以考虑一些使用Rxjs的方法,但是我不确定这意味着需要更少的代码。

你可以 :
-与使用Rx.Observable.fromEvent包装DOM事件的方式相同,包装busboy库事件。

然后执行以下操作:

var fileEvent$ = Rx.Observable.fromBusyBoyEvent('file');
var fieldEvent$ = Rx.Observable.fromBusyBoyEvent('field');
var finishEvent$ = Rx.Observable.fromBusyBoyEvent('finish');
var processFileEvent = function ( res, fieldname, file, filename, encoding, mimetype ) {
  /*code here*/
  return {res : /* something*/, done : false}
};
var processFieldEvent = function ( res, key, value, keyTruncated, valueTruncated ) {/*code here*/
  return {res : /* something*/, done : false}
};
var processFinishEvent = function ( res ) {return {res : res, done : true}};

var passReducer = function ( reduce_fn ) {
  return function () {
    return {args : arguments, reduce_fn : reduce_fn}
  }
};

var res$ = Rx.Observable
    .merge(
    fileEvent$.map(passReducer(processFileEvent)),
    fieldEvent$.map(passReducer(processFieldEvent)),
    finishEvent$.map(passReducer(processFinishEvent)))
    .scan(function ( acc, command ) {
            return command.reduce_fn.apply(null, command.args);
          }, {})
    .filter(function ( acc ) {return acc.done});

关于javascript - RxJS和Busboy,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33928132/

10-09 14:21