2017-03-05 16 views
2

非同期性のため、反応/還元アプリケーションでFileReader APIを使用するソリューションを設計するのに少し問題があります。私はいくつか見て回ったが、何も私のために働いていない。反応/還元でFileReaderを「同期的に」使用する方法

私はreact-dropzoneを使ってファイルの内容を取得し、後で内容を処理する反応コンポーネントを持っています。ファイル取得の、ドロップゾーンにコールバック火災を落としたときはいつでも:

onGuestListDrop = (fileData) => { 
    const headers = 
     FileParser.read(fileData) 
     .getHeaders(); 
    }; 

私の内部API設計の目的は、既存のシステムのフィールド名に列名をマッピングするために、.csvファイルまたは.xlsx形式のファイルのヘッダを取得することです。私はファイルの内容を解析するのに問題はありません。問題はFileReader.onloadイベントです。

マイトップleveのファイルパーサは次のとおりです。

class FileParser { 

    constructor(file) { 
    this.reader = new FileReader(); 
    this.init(file[0]); 
    return this; 
    } 

    static read(file) { 
    return new FileParser(file); 
    } 

    init(file) { 
    switch (file.type) { 
     case 'text/csv': 
     this.parser = new CsvParser(this.reader, file); 
     break; 

     default: 
     this.parser = new XlsParser(this.reader, file); 
     break; 
    } 
    } 

    getHeaders() { 
    return this.parser.getHeaders(); 
    } 
} 

CSVクラスは次のとおりです。

class CsvParser { 

    constructor(reader, file) { 
    this.reader = reader; 
    this.file = file; 
    this.parse(); 
    return this; 
    } 

    parse() { 
    this.reader.readAsText(this.file, "UTF-8"); 
    this.reader.onload = function (evt) { 
     const { result } = evt.target; 
     this.parsedContent = Papa.parse(result); 
     console.log(this.parsedContent); 
    }; 
    } 

    getHeaders() { 
    return this.parsedContent.data[0]; 
    } 
} 

問題が今あること私は私がgetHeadersメソッドを介してヘッダにアクセスしようとすると、 FileReaderは非同期で動作するため、未定義になります。いくつかのリファクタリングでこの作業を行う方法はありますか?これはちょうど不可能ですか?

私はreduxアクションを使用することを考えていましたが、パーサークラスをストアに接続する方法がわかりません。私は、FileReader.onloadイベント内でアクションクリエーターを起動できるように、アクションをパーサークラスに直接渡すことを考えました。私はこれがうまくいくと思っていますが、私はこれが状況を考えればレフィックスで働く最良の方法だとは確信していません。

+0

のようなあなたのonGuestListDrop方法を変更します。 –

答えて

1

CsvParserに遅延パターンをこのように追加します。

class CsvParser { 

constructor(reader, file) { 
    this.reader = reader; 
    this.file = file; 
    this.deferred = {}; 
    let promise = new Promise((resolve, reject) => { 
    this.deferred.resolve = resolve; 
    this.deferred.reject = reject; 
    }); 
    this.deferred.promise = promise; 
    this.parse(); 
    return this; 
} 

parse() { 
    this.reader.readAsText(this.file, "UTF-8"); 
    this.reader.onload = function (evt) { 
    const { result } = evt.target; 
    this.parsedContent = Papa.parse(result); 
    console.log(this.parsedContent); 
    this.deferred.resolve(this.parsedContent.data[0]) 
    }; 
} 

getHeaders() { 
return this.deferred.promise; 
} 

今、あなたが約束を使用する必要があり、この

onGuestListDrop = (fileData) => { 
    let headers = {}; 
    FileParser.read(fileData).getHeaders().then(function (headers) { 
    headers = headers; 
    }); 
}; 
関連する問題