2015-11-25 48 views
0

有一個busboy library。對於某些承諾庫,我可以用下面的代碼收集一個對象的整個表單數據:RxJS和Busboy

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來改進這個樣本?

+0

試試這個http://xgrommx.github.io/rx-book/content/observable/observable_methods/fromevent.html – xgrommx

+0

你建議設立3不同的序列(對於每種類型的事件),合併它們並減少一個對象? – kharandziuk

回答

1

我可以考慮一些使用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});