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(有和没有绑定)(不起作用)

为什么这在为tracksLoadedand工作时不起作用trackLoadedCount

关于 Firice Nguyen 答案的更新

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 回答