Я пытался сделать что-то, что я считаю относительно простым в Javascript (на срок более 12 часов), связанный с обратными вызовами и / или обещаниями.
Heads Up: я использую Rails с.js.erb
файл, но это не относится к моему вопросу, который больше сосредоточен на Javascript;показано только для иллюстрации большей проблемы.
Я использую jsmediatags для чтения метаданных из mp3 на удаленном хосте (в основном, для сбора обложек альбомов).Каждая «статья» на моем сайте соотносится с несколькими аудиофайлами (@related_titles
), поэтому я перебираю каждый из них (локальная переменная url
) и собираю иллюстрации, а затем отображаю их в плагине coverflow - это означает, что jsmediatags.read
выполняется один раз для каждого обрабатываемого mp3.Проблема в том, что ... jsmediatags не заканчивает читать все обложки до инициализации плагина coverflow.Несмотря на то, что я относительно новичок в js, мне кажется, что это идеальное использование функции обратного вызова.
Прямо сейчас я был вынужден ввести функцию 8500ms setTimeout
перед выполнением функции makeitrain
(который входит в прикрытие).Он работает, но он не надежен на всех устройствах (когда они находятся под нагрузкой), и это не элегантное решение.
Давайте предположим, что в @related_titles
есть 3 mp3-файла.Чтобы показать, что код не выполняется в правильном порядке (не ожидает обратного вызова?), Я добавил консольное ведение журнала.
Полученный вывод:
Gathered all art! Now I will callback and render the Coverflow
Initing Coverflow since gatherArtwork completed/we have art!
Gathering album art for title...
Gathering album art for title...
Gathering album art for title...
Ожидаемый результат:
Gathering album art for title...
Gathering album art for title...
Gathering album art for title...
Gathered all art! Now I will callback and render the Coverflow
Initing Coverflow since gatherArtwork completed/we have art!
Вот что я пробовал:
function gatherArtwork(_callback) {
// Read each of the mp3s to gather artwork ('url' == local var for mp3)
<% @related_titles.each do |url| %>
jsmediatags.read("<%= url['mp3'] %>", {
onSuccess: function(tag) {
console.log('Gathering album art for title...');
// Convert the image contents to a Base64 encoded str
var tags = tag.tags;
albumartwork = _arrayBufferToBase64(tags.picture["data"]);
// Append to the coverflow list a `<ul><li> </li></ul>` for each mp3
// The 'albumartwork' Base64 image str is also appended here
$("#coverflow-item-list").append('<ul><li>...</li></li>');
}
});
<% end %>
console.log('Gathered all art! Now I will callback and render the Coverflow');
_callback();
}
// Gather artwork MUST complete fully before the `makeitrain` function runs (callback)
function renderCoverflow() {
gatherArtwork(function() {
console.log('Initing Coverflow since gatherArtwork completed/we have art!');
makeitrain();
});
}
// Execute 'renderCoverflow' which will gather art and then "makeitrain"!
renderCoverflow();