Javascript 在第一次Ajax调用之后,DOM不是';t在第二个ajax调用之前更新';它取决于第一个
我正在创建一个应用程序,允许人们从一个列表拖动到一个插槽,然后插槽可以接受其中的几个子项,比如插槽a-1、a-2 所有这些交互都是通过jQueryUI的Javascript 在第一次Ajax调用之后,DOM不是';t在第二个ajax调用之前更新';它取决于第一个,javascript,jquery,ajax,jquery-ui,dom,Javascript,Jquery,Ajax,Jquery Ui,Dom,我正在创建一个应用程序,允许人们从一个列表拖动到一个插槽,然后插槽可以接受其中的几个子项,比如插槽a-1、a-2 所有这些交互都是通过jQueryUI的draggable和dropable完成的,但最终调用了函数,该函数包含一个Ajax调用来加载插槽及其子项的内容 需要注意的是,所有子项都依赖于插槽 据我所知,我尝试在$(document).ready()上模拟输入,由于ajax和函数在默认情况下是异步的,因此一些完成得更快,一些速度较慢,一些子项失败,因为此时插槽没有更新 我试着通过进行那些函
draggable
和dropable
完成的,但最终调用了函数,该函数包含一个Ajax
调用来加载插槽及其子项的内容
需要注意的是,所有子项都依赖于插槽
据我所知,我尝试在$(document).ready()
上模拟输入,由于ajax和函数在默认情况下是异步的,因此一些完成得更快,一些速度较慢,一些子项失败,因为此时插槽没有更新
我试着通过进行那些函数调用async
并等待函数来解决这个问题,但现在它根本不起作用,即使调用的顺序正确,这确实令人困惑
第二个ajax调用对第一个调用的依赖关系与第一个元素相关,第一个元素具有第二个调用所需的特定数据属性,并且由于某种原因,它总是未定义的,即使从技术上讲不应该定义。我将在下面的示例中进一步解释这一点:
我使用这种设置(它非常简单,但应该能够理解这一点):
现在,在LoadSlot内部,ajax调用一个PHP脚本,该脚本生成插入插槽的HTML。此HTML还包含必需的数据属性。为了100%确保数据信息也加载到jQuery中(因为我听说由于某种原因可能会出现一些问题),我手动更新LoadSlot()
调用中的数据,如下所示:
$(name).data("name",$(name).attr("data-name"));
我已经跟踪了调试,可以确认当调用$(name).attr(“data name”
不是未定义的/null,并且具有正确的值,这意味着在此之后,数据也应该是未定义的,但是直到所有javascript处理完,数据才保持未定义状态
此外,即使用于添加子项的函数出现在Slot调用之后,但一旦ajax错误警报出现,DOM仍然不包含它当时应该包含的HTML,就像它被卡住了一样,直到处理完所有代码,即使它不应该包含
一旦初始javascript结束并且我关闭了所有警报,我就可以从列表中进行拖放操作(同样,也可以执行相同的操作,调用LoadSlot()
或LoadSubitem()
,效果很好
所以问题基本上是这样的:
如何确保在调用
LoadSubitems()
之前,使用LoadSlots()
中的信息正确更新DOM?问题在于,您没有在LoadSlots()
中使用wait()
,因此它没有等待AJAX调用完成
async function LoadSlots()
{
await LoadSlot(x,y,z);
await LoadSlot(x,y,z);
await LoadSlot(x,y,z);
}
当然,这意味着您必须将LoadSlot()
编码为一个适当的异步函数。如果它调用$.ajax()
,您只需让它返回该调用,因为它返回一个承诺
如果不希望每个LoadSlot()
调用都等待前一个调用完成,可以使用Promise.all()
:
什么是
x
y
z
,为什么要调用LoadSlot()
和LoadSubItem()
3次使用相同的参数?您不会显示依赖于数据属性的代码,但我敢打赌您不会等待异步更新。@Barmar,我简化了调用,x、y和z,而不是随机参数,但从您的角度来看,我是否放置LoadSlot(.SlotPrimary”、“item”、1、1);
或LoadSlot(x,y,z);
其实不重要。另一方面,子项调用类似于:LoadSubitem(.SlotPrimary),$(.SlotPrimary.Info”),$(itemlist)。find('*[data name=“Subitem name”]');
这里从第二个参数(.Info)调用ajax时使用url:/Subitem.php?SlotId=“+$(Info).data('SlotId')+”&SubItemid=”+$(newSubitem).data('subitemid')+“&callback=?
和SubItemId是未定义的。我尝试过这个方法,但不幸的是结果是相同的。我尝试过用断点进一步调试代码,我注意到一个奇怪的现象。使用promise.all方法,我调用LoadSlot 5次,断点被命中5次。然后它在LoadSubitem中命中Ajax调用的断点,只有af完成这些操作后,它将命中LoadSlot ajax调用的成功函数。我认为这一承诺会确保ajax及其成功在代码继续到子项之前通过,但我猜不会。你知道为什么吗?我只是通过使依赖的ajax调用同步来修复它。不要这样做。LoadSlot()
以return$.ajax(…);
结束,就像我说的那样?很抱歉,我一定错过了那一行。不,没有。实际的Load**函数有额外的检查,ajax调用是有条件的。
async function LoadSlots()
{
await LoadSlot(x,y,z);
await LoadSlot(x,y,z);
await LoadSlot(x,y,z);
}
async function LoadSlots() {
await Promise.all([LoadSlot(x, y, z), LoadSlot(x, y, z), LoadSlot(x, y, z)]);
}