Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在第一次Ajax调用之后,DOM不是';t在第二个ajax调用之前更新';它取决于第一个_Javascript_Jquery_Ajax_Jquery Ui_Dom - Fatal编程技术网

Javascript 在第一次Ajax调用之后,DOM不是';t在第二个ajax调用之前更新';它取决于第一个

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和函数在默认情况下是异步的,因此一些完成得更快,一些速度较慢,一些子项失败,因为此时插槽没有更新 我试着通过进行那些函

我正在创建一个应用程序,允许人们从一个列表拖动到一个插槽,然后插槽可以接受其中的几个子项,比如插槽a-1、a-2

所有这些交互都是通过jQueryUI的
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)]);
}