从回调中写入/调整对象

Writing/adjusting object from within callback

本文关键字:调整 对象 回调      更新时间:2023-09-26

我正在处理一个流星反应项目,希望使用来自本地存储的异步加载数据。不幸的是,即使使用绑定,我也无法从回调中获取数据。我尝试了多种方法,但都没能让它们发挥作用,我肯定错过了一些东西。

我尽可能多地脱光衣服,但不得不保留一些以备不时之需。

根据我的理解,它只能与轨迹对象相关,因为设置那些简单的整数,布尔运算效果很好。

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

为什么它在为tracksLoadedtrackLoadedCount工作时不起作用?

关于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

因此,问题依然存在。

forEach给出元素的副本。track只是一个副本,而不是原来的。它不指向数组中的元素。你可以试试这个:

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

或者尝试映射方法