0

私は隕石反応プロジェクトに取り組んでおり、非同期に発生するローカルストレージからのロードデータを使用したいと考えています。残念ながら、バインドしてもコールバックからデータを取得できませんでした。複数の方法を試しましたが、どれも機能しませんでした。確かに何かが欠けています。

可能な限り削除しましたが、コンテキストのためにいくつかを保持する必要がありました.

私の理解では、これらの単純な整数を設定すると、トラックオブジェクトにのみ関連する可能性があり、ブール値は正常に機能します。

render() {
    const { audioCollection } = this.props; // database collection, async hence the following if check
    if (audioCollection) {
        this.tracks = audioCollection.audio(); // setting tracks for later use
        // make sure tracks are loaded and only run once, as we do this in the react renderer
        if (this.tracks && !this.state.tracksLoaded) { 
            var trackLoadedCount = 0;
            this.tracks.forEach((track, i) => { // I tried to use forEach and map here
                // now we try to load the data from local storage and if it fails fall back to the remote server
                LocalForage.getItem(track.file_id).then(function(err, file) {
                    if (!err && file) {
                        console.log(track.file_id + ' from cache')
                        var blob = new Blob([file]);
                        fileURI = window.URL.createObjectURL(blob);
                    } else {
                        console.log(track.file_id + ' from database')
                        fileURI = audioCollection.audioLink(track.file_id);
                    }
                    track.fileURI = fileURI; // assigning the retrieved data uri to the track object, also tried to set it on the original parent object not the extracted one from the forEach/map
                    console.log(fileURI + ' ' + track.fileURI) // yes, both are set
                    trackLoadedCount++; // increasing the tracks loaded count, to calculate if all have been loaded and to test if it can write outside of the callback, which it does
                    // if all files have been processed, set state loaded, this works too.
                    if (trackLoadedCount == this.tracks.length) {
                        this.setState({
                            tracksLoaded: true,
                        })
                    }
                }.bind(track, this))
            });
        }
    }
    // once all has been processed we try to retrieve the fileURI, but it isn't set :(
    if (audioCollection && this.tracks && this.state.tracksLoaded) {
        console.log('all loaded ' + this.tracks.length)
        this.tracks.map(track => {
            console.log('track: ' + track.file_id + ' ' + track.fileURI) // file_id is set, fileURI is not
        })
    }

    // we only log
    return (
        <Content {...this.props}>
            <div>just console output</div>
        </Content>
    );
}

私はより多くのアプローチを試しました:

  • トラックを配列として書き込んで、次のように状態にしますtracksLoaded(うまくいきませんでした)
  • 非同期呼び出しの前に新しい var を定義し、その値をコールバック内から設定するtrackLoadedCount(バインドの有無にかかわらず) (機能しません)

tracksLoadedと で機能しているのに、これが機能しないのはなぜtrackLoadedCountですか?

Firice Nguyen Answer に関する最新情報

render() {
    const { audioCollection } = this.props;
    if (audioCollection) {
        this.tracks = audioCollection.audio();
        if (this.tracks && !this.state.tracksLoaded) {
            var trackLoadedCount = 0;
            this.tracks.forEach((track, i, trackArray) => {
                LocalForage.getItem(track.file_id).then(function(err, file) {
                    if (!err && file) {
                        console.log(track.file_id + ' from cache')
                        var blob = new Blob([file]);
                        fileURI = window.URL.createObjectURL(blob);
                    } else {
                        console.log(track.file_id + ' from database')
                        fileURI = audioCollection.audioLink(track.file_id);
                    }
                    track.fileURI = fileURI;
                    console.log('1. ' + track.file_id + ' ' + track.fileURI);
                    trackArray[i] = track;
                    console.log('2. ' + track.file_id + ' ' + trackArray[i].fileURI);
                    trackLoadedCount++;
                    if (trackLoadedCount == this.tracks.length) {
                        this.setState({
                            tracksLoaded: true,
                        })
                    }
                }.bind(track, this))
            });
        }
    }
    if (audioCollection && this.tracks && this.state.tracksLoaded) {
        console.log('all loaded ' + this.tracks.length)
        this.tracks.map(track => {
            console.log('3. ' + track.file_id + ' ' + track.fileURI) // file_id is set, fileURI is not
        })
    }

    return (
        <Content {...this.props}>
            <div>just console output</div>
        </Content>
    );
}

戻り値

MXqniBNnq4zCfZz5Q from database
1. http://localhost:3000/cdn/storage/files/MXqniBNnq4zCfZz5Q/original/MXqniBNnq4zCfZz5Q.m4a
2. http://localhost:3000/cdn/storage/files/MXqniBNnq4zCfZz5Q/original/MXqniBNnq4zCfZz5Q.m4a
keBWP6xb9PyEJhEzo from database
1. http://localhost:3000/cdn/storage/files/keBWP6xb9PyEJhEzo/original/keBWP6xb9PyEJhEzo.m4a
2. http://localhost:3000/cdn/storage/files/keBWP6xb9PyEJhEzo/original/keBWP6xb9PyEJhEzo.m4a
K2J2W9W26DDBNoCcg from database
1. http://localhost:3000/cdn/storage/files/K2J2W9W26DDBNoCcg/original/K2J2W9W26DDBNoCcg.m4a
2. http://localhost:3000/cdn/storage/files/K2J2W9W26DDBNoCcg/original/K2J2W9W26DDBNoCcg.m4a
all loaded 3
3. MXqniBNnq4zCfZz5Q undefined
3. keBWP6xb9PyEJhEzo undefined
3. K2J2W9W26DDBNoCcg undefined

したがって、問題は解決しません。

4

1 に答える 1

0

要素のforEachコピーを配布します。trackオリジナルではなくただのコピーです。配列内の要素を指していません。これを試すことができます:

this.tracks.forEach(track, i, trackArray) => {
    // change `track` value
    ...
    trackArray[i] = track;
});

またはmapメソッドを試してください

于 2016-07-20T14:35:04.780 に答える