Vue3.0异步调用数据时,数据顺序不一致问题

在弄毕设的时候,要弄一个歌曲推荐页面,推荐歌曲已经通过Spark引擎已经处理好,存储在mysql数据库。现在要根据用户id,从数据库中选取推荐给该用户的全部歌曲id,再通过选出的歌曲id选出歌曲详细信息。

有了歌曲id列表后,需要遍历这个列表取出歌曲详细数据。

开始使用then来获取异步数据

if (store.getters.token) {
    // store.getters.username还要拿到username后,还得使用.value才能取出用户名称
    // 获取用户id
    const userId = computed(() => store.getters.userId);
    const songId = await HttpManager.getListSongRecommendOfSongId(userId.value);
    console.log("songId", songId);
    const index = ref(1);
    songId.data.forEach((item: any, index) => {
        console.log("songInfo", item.songId);
        HttpManager.getSongBaseOfId(item.songId).then( res => {
            console.log("res", res);
            res.data[0]["songName"] = getSongTitle(res.data[0].name);
            res.data[0]["singerName"] = getSingerName(res.data[0].name);
            res.data[0]["index"] = index;
            dataList.value.push(res.data[0]);
        })
    });
    console.log("dataList", dataList);

} else {
    // 推荐热榜前15首歌曲
    HttpManager.getSongTop().then((res) => {
        res.data.slice(0, 10).forEach((item: any, index) => {
            item["songName"] = getSongTitle(item.name);
            item["singerName"] = getSingerName(item.name);
            item["index"] = index;
            // list.push(item);
            dataList.value.push(item);
        });
        // dataList.value = list
    });
}

获取歌曲id的数据顺序还一致

const songId = await HttpManager.getListSongRecommendOfSongId(userId.value);

但通过歌曲id获取歌曲信息时,和songId里数据的顺序不一致,dataList第一条数据是M005891,和在songId里数据的顺序不一致

而且刷新页面后,这个dataListd的数据还会发生变化,这可能是异步调用的问题

接下来就解决这个数据顺序问题

使用foreach() + await来获取数据

开始使用then来获取数据,数据顺序会乱,所以先采用直接用foreach() + await来获取数据

// 用户登陆了才个性化推荐
if (store.getters.token) {
    // store.getters.username还要拿到username后,还得使用.value才能取出用户名称
    // 获取用户id
    const userId = computed(() => store.getters.userId);
    const songId = await HttpManager.getListSongRecommendOfSongId(userId.value);
    console.log("songId", songId);
    const index = ref(1);
    songId.data.forEach((item: any, index) => {
        console.log("songInfo", item.songId);
        const songInfo = await HttpManager.getSongBaseOfId(item.songId);
        console.log("songInfo", songInfo.data[0]);
        // console.log("songInfovalue", songInfo.data.value);
        songInfo.data[0]["songName"] = getSongTitle(songInfo.data[0].name);
        songInfo.data[0]["singerName"] = getSingerName(songInfo.data[0].name);
        songInfo.data[0]["index"] = index;
        dataList.value.push(songInfo.data[0]);
        index.value += 1
    });
    console.log("dataList", dataList);

} else {
    // 推荐热榜前15首歌曲
    HttpManager.getSongTop().then((res) => {
        res.data.slice(0, 10).forEach((item: any, index) => {
            item["songName"] = getSongTitle(item.name);
            item["singerName"] = getSingerName(item.name);
            item["index"] = index;
            // list.push(item);
            dataList.value.push(item);
        });
        // dataList.value = list
    });
}

 这句代码能够获取对应的歌曲id列表

const songId = await HttpManager.getListSongRecommendOfSongId(userId.value);

但下面的根据id获取歌曲信息的代码就报错了

songId.data.forEach((item: any, index) => {
        console.log("songInfo", item.songId);
        const songInfo = await HttpManager.getSongBaseOfId(item.songId);
        console.log("songInfo", songInfo.data[0]);
        // console.log("songInfovalue", songInfo.data.value);
        songInfo.data[0]["songName"] = getSongTitle(songInfo.data[0].name);
        songInfo.data[0]["singerName"] = getSingerName(songInfo.data[0].name);
        songInfo.data[0]["index"] = index;
        dataList.value.push(songInfo.data[0]);
        index.value += 1
    });

const songInfo = await HttpManager.getSongBaseOfId(item.songId);

使用for...of + await来获取数据

后面发现,使用for...of + await 这个语句可以运行,并且成功拿到数据

for (const item of songId.data) {
        console.log("songInfo", item.songId);
        const songInfo = await HttpManager.getSongBaseOfId(item.songId);
        console.log("songInfo", songInfo.data[0]);
        // console.log("songInfovalue", songInfo.data.value);
        songInfo.data[0]["songName"] = getSongTitle(songInfo.data[0].name);
        songInfo.data[0]["singerName"] = getSingerName(songInfo.data[0].name);
        songInfo.data[0]["index"] = index;
        dataList.value.push(songInfo.data[0]);
        index.value += 1
    }
    console.log("dataList", dataList);

没报错并且顺序是正确的,出现了个新问题,就是在页面上没显示。。。

使用for...of + await + async获取数据

后面又发现,await要和async一起使用,于是再外面套了一层async函数,通过这个函数的async,拿到数据后,也能在页面上显示了。这个函数只是套了一层,核心还是上面那些从数据库读数据的代码

// 获取推荐歌曲
const fetchData = async () => {
    try {
        // 用户登陆了才个性化推荐
        if (store.getters.token) {
            // store.getters.username还要拿到username后,还得使用.value才能取出用户名称
            // 获取用户id
            const userId = computed(() => store.getters.userId);
            const songId = await HttpManager.getListSongRecommendOfSongId(userId.value);
            console.log("songId", songId);
            const index = ref(1);
            for (const item of songId.data) {
                console.log("songInfo", item.songId);
                const songInfo = await HttpManager.getSongBaseOfId(item.songId);
                console.log("songInfo", songInfo.data[0]);
                // console.log("songInfovalue", songInfo.data.value);
                songInfo.data[0]["songName"] = getSongTitle(songInfo.data[0].name);
                songInfo.data[0]["singerName"] = getSingerName(songInfo.data[0].name);
                songInfo.data[0]["index"] = index;
                dataList.value.push(songInfo.data[0]);
                index.value += 1
            }
            console.log("dataList", dataList);

        } else {
            // 推荐热榜前15首歌曲
            HttpManager.getSongTop().then((res) => {
                res.data.slice(0, 10).forEach((item: any, index) => {
                    item["songName"] = getSongTitle(item.name);
                    item["singerName"] = getSingerName(item.name);
                    item["index"] = index;
                    // list.push(item);
                    dataList.value.push(item);
                });
                // dataList.value = list
            });
        }
    } catch (error) {
        console.error('Error fetching data:', error);
    }
};
fetchData()

然后,页面就有显示了,真是,这也能跑??