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

如何让JavaScript的appendElement函数等待createForm及updateValues执行完成(无需setTimeout)?

解决方案:用Promise等待用户交互完成

我明白你的问题了——你当前的async/await根本没起到等待作用,因为createForm里的await updateValues(number)是函数执行时立刻同步调用的,但实际上updateValues是用户点击"Add"按钮才会触发的操作,这时候createForm早就跑完了,addPlace里的appendElement自然不会等用户输入完成。

咱们用Promise来包裹用户的交互逻辑,让createForm返回一个Promise,只有当用户完成点击操作、updateValues执行完毕后,这个Promise才会resolve,这样addPlace里的await就能真正等待用户操作完成。

修改步骤&核心代码

1. 改造createForm,让它返回Promise

把用户的交互操作包裹在Promise里,保存resolve函数,等用户点击按钮时再触发它:

// 改造createForm,返回Promise
function createForm(number){
 return new Promise((resolve) => {
 console.log(`locationName_${number}`);
 let items = `key, phone, book,...`;
 let newForm = ` 
<div id="container" class="d-flex align-items-stretch">
 <div class="reveal-modal d-flex flex-column bd-highlight mb-3" id="exampleModal">
 <div class="mb-3 d-flex flex-column ">
 <label for="locationName" class="form-label">Location</label>
 <input type="name" class="form-control" id="updateLocationName_${number}" placeholder="Location Name">
 <label for="Lost items" class="form-label">Lost items<br>Please separate items with comma (,)</label>
 <input type="name" class="form-control" id="updatedLocationItems_${number}" placeholder="${items}">
 </div>
 <div>
 <button class="btn btn-primary" onclick="deleteListCard('container')">Cancel</button>
 <!-- 修改按钮点击事件,传入resolve函数 -->
 <button class="btn btn-primary" onclick="updateValues(${number}, resolve)">Add</button>
 </div>
 </div>
 </div>
 `;
 const parentDom = document.querySelector('body');
 parentDom.innerHTML += newForm;
 });
}

2. 调整updateValues,完成操作后resolve Promise

让updateValues接收resolve参数,在完成localStorage设置和弹窗关闭后,触发resolve告知Promise完成:

// 接收resolve参数,完成后触发resolve
async function updateValues(number, resolve){
 console.log(`${number} is updated!`);
 let updatedName = document.getElementById(`updateLocationName_${number}`).value;
 let updatedItems = document.getElementById(`updatedLocationItems_${number}`).value;
 console.log(updatedName);
 console.log(updatedItems);
 const itemArr = updatedItems.split(',');
 // 存入localStorage
 localStorage.setItem(`locationName_${number}`, updatedName);
 localStorage.setItem(`locationItems_${number}`, JSON.stringify(itemArr));
 deleteListCard('container'); // 关闭弹窗
 // 触发resolve,告诉createForm的Promise已完成
 resolve();
}

3. 保留原addPlace逻辑即可

现在addPlace里的await createForm(idNum)会真正等待用户操作完成,再执行appendElement:

async function addPlace (){
 await createForm(idNum);
 appendElement("listParent", idNum);
 idNum += 1;
};

完整修改后代码

async function addPlace (){
 await createForm(idNum);
 appendElement("listParent", idNum);
 idNum += 1;
};

// 改造createForm,返回Promise
function createForm(number){
 return new Promise((resolve) => {
 console.log(`locationName_${number}`);
 let items = `key, phone, book,...`;
 let newForm = ` 
<div id="container" class="d-flex align-items-stretch">
 <div class="reveal-modal d-flex flex-column bd-highlight mb-3" id="exampleModal">
 <div class="mb-3 d-flex flex-column ">
 <label for="locationName" class="form-label">Location</label>
 <input type="name" class="form-control" id="updateLocationName_${number}" placeholder="Location Name">
 <label for="Lost items" class="form-label">Lost items<br>Please separate items with comma (,)</label>
 <input type="name" class="form-control" id="updatedLocationItems_${number}" placeholder="${items}">
 </div>
 <div>
 <button class="btn btn-primary" onclick="deleteListCard('container')">Cancel</button>
 <!-- 修改按钮点击事件,传入resolve函数 -->
 <button class="btn btn-primary" onclick="updateValues(${number}, resolve)">Add</button>
 </div>
 </div>
 </div>
 `;
 const parentDom = document.querySelector('body');
 parentDom.innerHTML += newForm;
 });
}

// 接收resolve参数,完成后触发resolve
async function updateValues(number, resolve){
 console.log(`${number} is updated!`);
 let updatedName = document.getElementById(`updateLocationName_${number}`).value;
 let updatedItems = document.getElementById(`updatedLocationItems_${number}`).value;
 console.log(updatedName);
 console.log(updatedItems);
 const itemArr = updatedItems.split(',');
 // set Array
 localStorage.setItem(`locationName_${number}`, updatedName);
 localStorage.setItem(`locationItems_${number}`, JSON.stringify(itemArr));
 deleteListCard('container'); //exit popup
 // 触发resolve,告诉createForm的Promise已经完成
 resolve();
}

//Append List
function appendElement(parentID, number){
 const parentDom = document.getElementById(parentID);
 if(document.getElementById("stevens_barbar")){
 deleteListCard("stevens_barbar");
 }
 let location = localStorage.getItem(`locationName_${number}`);
 let storedItems = JSON.parse(localStorage.getItem(`locationItems_${number}`));
 parentDom.innerHTML += ` 
<div id="location_${number}">
 <h1>${location}</h1>
 ${generateCheckbox(storedItems)}
 <div>
 <button class="btn btn-primary" onclick="updateLocalstorage('${number}')">Edit</button>
 <button class="btn btn-warning delete_button" onclick="deleteListCard('location_${number}')">Delete</button>
 </div>
 </div>
 `;
}

这样修改后,你不需要刷新页面,appendElement创建的卡片会直接读取最新的localStorage值,完美解决你的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 00:49:06