You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Promise生成动态HTML时数据无法正确渲染的问题

问题

使用返回Promise的函数生成动态HTML时,可通过createClientElement创建全部clientMain元素,但仅能填充第一个元素的订单内容,其余元素无法正确渲染订单项。

核心问题原因
  1. 重复创建元素:每个订单子项都会调用createClientElement,导致同一订单对应的clientMain被重复生成,后续的append操作只会匹配到第一个创建的元素。
  2. 异步流程混乱:嵌套的Promise回调和$.ajax异步操作顺序失控,子项渲染可能在元素创建完成前执行,或因重复元素导致选择器失效。
  3. ID命名冲突:内层循环的i作为子项ID的一部分,不同订单的子项可能出现ID重复问题。
修复代码

重构previousOrders函数

function previousOrders(){
    UniqueOrderIdList.forEach(async (orderId, index) => {
        const orderItemsByIdURL = `${base_url}${orderItemsPath}${url_auth}&order_id=${orderId}`;
        
        try {
            // 获取当前订单的所有子项
            const orderItemsRes = await $.ajax({
                url: orderItemsByIdURL,
                type: "GET",
                data: {}
            });
            const data = orderItemsRes.data;

            // 仅创建一次当前订单的client容器
            const clientId = await getClientId(orderId);
            await createClientElement(clientId, index);

            // 批量处理所有订单子项
            const itemPromises = data.map(async (item, itemIndex) => {
                const { widget_id: widgetId, number: Number, pence_price: PencePrice } = item;
                const price = parseFloat(PencePrice/100).toFixed(2);
                
                const productDesc = await getProdDesc(widgetId);
                
                // 生成带唯一ID的子项模板
                const template2 = `
                <div>
                    <p class="orderdsc" id="orderdsc_${index}_${itemIndex}">${Number}: ${productDesc}
                        <span class="orderItemid" id="orderItemid_${index}_${itemIndex}">ID:${clientId}</span>
                        <span class="orderPrice" id="orderPrice_${index}_${itemIndex}">£${price}</span>
                    </p>
                </div>`;
                
                $(`#pastOrderItems_${index}`).append(template2);
            });

            await Promise.all(itemPromises);
        } catch (err) {
            console.error("订单处理失败:", err);
        }
    });
}

可选优化getClientId(移除不必要的延迟)

function getClientId(orderId){
    return new Promise((resolve, reject) => {
        const prodDescURL = `${base_url}${ordersPath}${orderId}${url_auth}`;
        
        function getSuccess(obj){
            if (obj.status == "success") {
                const clientId = obj.data[0].client_id;
                resolve(clientId);
            } else if (obj.message) {
                reject(new Error(obj.message));
            } else {
                reject(new Error("无效请求"));
            }
        }

        $.ajax(prodDescURL, {type: "GET", data: {},success: getSuccess });
    });
}
修复要点
  • 单次创建容器:每个订单仅调用一次createClientElement,在处理子项前完成容器创建
  • 简化异步流程:用async/await替代嵌套Promise回调,明确控制异步操作顺序
  • 唯一ID标识:子项ID改为orderdsc_${index}_${itemIndex},避免跨订单ID冲突
  • 批量处理子项:用Promise.all等待所有子项渲染完成,保证流程完整性
期望的最终HTML结构
<div id="pastOrdersINPUT">
  <div class="clientMain">
    <div id="clients">
      <p class="client top" id="clientName">Client name: ${client_name}</p>
      <p class="client" id="clientAddress">Client address: ${client_address}</p>
      <p class="client" id="clientPhone">Client phone: ${client_phone}</p>
      <p class="client bottom" id="clientEmail">Client email: ${client_email}</p>
    </div>
    <div class="order" id="pastOrderItems_0">
      <div>
        <p class="orderdsc" id="orderdsc_0_0">${Number}: ${productDesc}
          <span class="orderItemid" id="orderItemid_0_0">ID:${clientId}</span>
          <span class="orderPrice" id="orderPrice_0_0">£${price}</span>
        </p>
      </div>
      <!-- 同订单的其他子项 -->
    </div>
  </div>
  <!-- 其他订单的clientMain容器 -->
</div>

内容的提问来源于stack exchange,提问作者qwerty12butt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 01:47:13