jQuery中append追加数据与服务端降序排序不一致如何解决
问题原因
你遇到的排序混乱是因为for循环内发起的getchatdet是异步AJAX请求,异步请求的响应返回时间不固定,先发的请求可能后返回,append操作会在请求返回后立刻执行,最终渲染顺序就和服务端返回的原始排序不一致。
解决方法
推荐使用Promise.all统一处理所有异步请求,等所有请求完成后按原始发起顺序统一渲染,完全保留服务端排序。
修改后代码:
$(document).on('click', '#jhchat', function() { const $messageModa = $('.jhchat').find('.messagemoda'); $messageModa.html(''); const jus = '{{Auth::user()->id}}'; $.ajax({ url: '{{url("getuchats")}}', type: 'post', data: { _token: CSRF_TOKEN }, success: async function(data) { if (data.length > 0) { // 按原始顺序收集所有请求Promise const requestList = []; for (var i = 0; i < data.length; i++) { let mid; if (data[0].s_id == jus) { mid = data[i].r_id; } else { mid = data[i].s_id; } // 把每个ajax包装成Promise,放进请求列表 requestList.push(new Promise((resolve) => { $.ajax({ url: '{{url("getchatdet")}}', type: 'post', data: { _token: CSRF_TOKEN, 'mid': mid, 'chid': data[i].id }, success: function(res) { resolve(res); } }); })); } // 等待所有请求完成,按原始顺序返回结果 const resList = await Promise.all(requestList); // 按顺序渲染所有内容 resList.forEach(res => { $messageModa.append(` <div class="row mt-3 conv${res.chat.id}" alt="${res.chat.id}"> <div class="col-11 row mt-2 ads chads cchat${res.chat.id}" alt="${res.chat.id}" id="${res.mid}"> <div class="col-3" style="padding-left: 5px;"> <img src="${res.img}" alt="home" width="60" height="60" class="rounded-circle"> </div> <div class="col-8"> <h6 class="mt-4 text-end">${res.name} ${res.mescount > 0 ? '<span class="me-4" style="color: crimson;background-color: bisque;border-radius: 50%;padding-left: 5px;padding-right: 5px;">' + res.mescount + '</span>' : ''}</h6> </div> </div> <div class="col-1 mt-4 ps-0 ms-0 float-start text-start" style="position: relative;"> <img src="{{url('images/menu.png')}}" alt="${res.chat.id}" width="32px" height="32px" class="hmenu" style="cursor: pointer;background-color: #eee;border-radius: 50%;padding:8px;"> <div class="smenu${res.chat.id} jsmen">${res.justo > 0 ? '<a class="me-2 jsmenitem d-block" href="' + res.s + '">go store <img style="margin-right: 2rem;" src="{{url('images / arrow1.png ')}}" width="13px" height="13px"></a>' : ''} <p class="text-danger delconv mt-2 mb-0 me-2 jsmenitem" alt="${res.chat.id}" style="cursor: pointer;">delete <img style="margin-right: 3.4rem;" src="{{url('images/close1.png')}}" width="10px" height="10px"></p> </div> </div> </div>`); }); $(".messagemoda").trigger("update"); } else { $messageModa.html('<div class="mt-5 text-center">no data</div>'); } } }); $('.adsopa').css('opacity', '0.3'); $('.sidebarmenu').removeClass('active'); $('.jhchat').css("display", "block"); $('body').css('overflow-y', 'hidden'); });
其他可选方案
如果需要逐步加载内容不想等所有请求完成再渲染,可以在发起请求前按顺序先往容器插入占位div,请求返回后找到对应位置的占位div填充内容,也可以保证顺序正确。
内容的提问来源于stack exchange,提问作者jvd
相关产品推荐
相关产品推荐

