JavaScript中如何在for循环中仅执行一次initPlayer()函数?
我查阅了许多类似问题但未找到答案,因此提出此问题。
我正在开发一项功能,允许用户播放当前页面上的所有音轨。不过,要让音频播放器首次在页面上显示,用户点击「全部播放」按钮时至少需要调用一次initPlayer()。
问题在于,我使用for循环遍历数组中的所有歌曲ID以填充播放列表:
var theids = ids.split(","); for (var i = 0; i < theids.length; i++) { getItem(theids[i], type).done(function(obj) { if (obj.status == 'success') { mep.mepPlaylistTracks = obj.tracks; initPlayer(); addToPlay(obj.tracks, play); } }); }
initPlayer()首次初始化时依赖getItem()函数返回的信息,因此必须按此顺序编写代码。
有没有办法让initPlayer()在for循环中仅执行一次?它现在会在每首歌添加到播放列表时重新初始化,引发性能和视觉问题。这种需求在JavaScript中是否可行?
补充initPlayer()和getItem()函数代码。我刚接触JavaScript,感谢任何帮助。
// init player function initPlayer(){ $('.app-player').removeClass('hide'); $('#app').removeClass('hide-player'); var playlist = $( '.playlist' ).mepPlaylist({ audioHeight: '40', audioWidth: '100%', videoHeight: '40', videoWidth: '100%', audioVolume: 'vertical', mepPlaylistLoop: true, alwaysShowControls: true, mepSkin: 'mejs-audio', mepResponsiveProgress: true, mepAutoPlay: false, mepSelectors: { playlist: '.playlist', track: '.track', tracklist: '.tracks' }, features: [ //'meplike', 'mepartwork', 'mepcurrentdetails', 'mepplaylist', 'mephistory', 'mepprevioustrack', 'playpause', 'mepnexttrack', 'progress', 'current', 'duration', 'volume', 'mepicons', 'meprepeat', 'mepshuffle', 'mepsource', 'mepbuffering', 'meptracklist', 'mepplaylisttoggle', 'youtube' ], mepPlaylistTracks: mep.mepPlaylistTracks }); } function getItem(id, type){ return $.ajax({ type : "post", dataType : "json", url : ajax.ajax_url, data : {action: "ajax_music", id: id, type: type, nonce: ajax.nonce} }); }
嘿,这个需求完全可行!核心思路就是加一个初始化状态标记,用来控制initPlayer()只在第一次AJAX请求成功时执行一次,后续的请求只负责把曲目添加到播放列表里。
具体修改步骤很简单:
- 添加初始化标记:在循环外面定义一个变量,用来记录播放器是否已经初始化完成。
- 修改回调逻辑:在AJAX的
done回调里,先检查这个标记——如果还没初始化,就调用initPlayer()并把标记设为true;之后的请求就只执行addToPlay()来添加曲目。
修改后的代码如下:
var theids = ids.split(","); let playerInitialized = false; // 新增:初始化状态标记 for (var i = 0; i < theids.length; i++) { getItem(theids[i], type).done(function(obj) { if (obj.status == 'success') { mep.mepPlaylistTracks = obj.tracks; // 只在播放器未初始化时执行initPlayer() if (!playerInitialized) { initPlayer(); playerInitialized = true; // 标记为已初始化 } addToPlay(obj.tracks, play); // 所有成功的请求都添加曲目 } }); }
为什么这样有效?
因为AJAX请求是异步的,第一个成功返回的请求会触发播放器初始化,之后的请求因为playerInitialized已经是true,就会跳过initPlayer()的调用,只执行曲目添加操作。这样既保证了播放器能依赖第一个返回的obj.tracks完成初始化,又避免了重复初始化带来的性能和视觉问题。
如果担心所有AJAX请求都失败的情况,你还可以在循环结束后加个额外判断(比如用Promise.all等待所有请求完成,再检查是否有成功的请求且未初始化播放器),不过根据你的需求,上面的修改应该已经能解决问题啦!
内容的提问来源于stack exchange,提问作者anthonyCam

