Я работаю над проектом реакции на метеор и хочу использовать данные загрузки из локального хранилища, которые происходят асинхронно. К сожалению, я не смог получить данные из обратного вызова даже с привязками. Я пробовал несколько способов, но не смог заставить ни один из них работать, наверняка я что-то упускаю.
Я вырезал столько, сколько мог, но кое-что пришлось оставить для контекста.
Насколько я понимаю, это может быть связано только с объектом дорожки, поскольку установка этих простых целых чисел, логические значения работают нормально.
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
(не работает) - Определение новой переменной перед асинхронным вызовом и установка ее значений из обратного вызова, например
trackLoadedCount
(с привязкой и без нее) (не работает)
Почему это не работает, хотя работает для tracksLoaded
и trackLoadedCount
?
Обновление относительно ответа Фирис Нгуен
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
поэтому проблема сохраняется.