javascript - 尝试在 Chrome 中使用 jQuery 同步 AJAX + .ready() 时出现不可预测的行为

标签 javascript jquery ajax

我正在开发一个使用 jQuery 的网络应用程序,并且在测试时我得到了一些看起来可能是竞争条件的东西。尽管我尽了最大努力,但我不确定如何继续。

密码在GitHub ,但我将在此处总结奇怪的行为。

早期 AJAX 请求

我有一些代码需要 AJAX 调用并准备好 DOM。为了加快速度,我在 $(document).ready() 事件触发之前进行 AJAX 调用。在链接的 JS 文件中,这是“init”函数。此函数调用 _build_site_select,它设置 AJAX 请求。完成后,将调用 _on_site_list_success。

在 $(document).ready() 上

当我到达 ready() 时,我进行了需要同时触发 AJAX 和 ready() 事件的调用。在链接代码中,这是 populate_site_select 调用。由于调用 ready() 时 AJAX 可能未完成,因此我检查了在 AJAX 操作完成后设置的变量,并使用 setTimeout 延迟对 populate_site_select 的调用(如果完成时间还早)。变量 site_list_ready 在 AJAX 调用完成时设置,并在需要站点列表在执行前完全完成的函数中检查。

预期和观察到的行为

我希望看到的行为是 populate_site_select 仅在 _on_site_list_select 中的对象/关联数组完全填充后才会被调用。然而,这并非总是如此。有时,当我到达 populate_site_select 时,数组仅部分填充 - 它失败的方式似乎是一致的(它始终是数组中的相同单个条目,而不是我期望的 ~30 左右)。

我尝试过的

我还尝试向 _on_site_list_success 调用添加一个 setTimeout 调用,这进一步将数组的填充与 site_list_ready 变量的设置分开。但是,这并不能解决问题。

我知道从 AJAX 调用返回的 JSON 数据是正确的(我可以在 chrome 调试器中查看它),如果我稍后检查站点列表变量的值,(在页面加载完成后)它是正确的人口稠密。

这似乎不是一个不寻常的场景,我很难相信这个错误是在 Chrome 中(尽管我没有用其他浏览器测试过这个)。我做错了什么?

最佳答案

我没有尝试下面的代码,但 jQuery 的 Deferred 对象可以帮助您。

var domReady, ajax;
domReady = jQuery.Deferred();

jQuery(function () {
    // on DOM ready
    domReady.resolve();
});

ajax = jQuery.ajax({
  url: '/path/to/file',
  type: 'GET',
  dataType: 'xml/html/script/json/jsonp'
});

jQuery.when(domready, ajax).then(doneCallbacks, failCallbacks);

基本上,您有两个延迟对象,一个处理 DOM 就绪状态,第二个处理 AJAX 调用;我们手动管理第一个对象,在 DOM 准备好时解析它;第二个由 jQuery 本身自动管理($.ajax 对象是 Deferred 对象,并在 AJAX 调用成功时解析)。

最后,使用 jQuery.when() 我们观察延迟对象的状态,当它们被解析时,doneCallback 被解雇;如果两个对象之一被拒绝,则 failCallback 被触发。

因此,doneCallbacks 是将在解析两个 Deferred 对象后调用的函数,以便 DOM 准备就绪并且 AJAX 调用已进行并成功。

请参阅 jQuery.when() 的文档和 Deferred objects

关于javascript - 尝试在 Chrome 中使用 jQuery 同步 AJAX + .ready() 时出现不可预测的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10364447/

相关文章:

javascript - 使用 Jasmine 在对象上测试事件处理程序

javascript - jQuery 网站预加载器,例如 Tuts+(示例网站)

javascript - 返回 false 后提交表单

javascript - 使用AJAX抓取JSON数据,然后通过ElementID在HTML上输出数据

php - 使用Ajax并将JS变量传递给php变量,$_POST无法识别数据值

javascript - 将图像添加到多个谷歌地图信息窗口

javascript - 过滤嵌套数组

javascript - SoundCloud API - 列出用户的关注用户名

javascript - 防止在 JavaScript 禁用或不可用时提交使用 AJAX 提交的表单

javascript - 使用 jQuery 删除表但不删除表单和字段