【发布时间】:2013-09-07 06:06:31
【问题描述】:
我有两个 jsbin 的代码说明:
http://jsbin.com/OdiSApI/1/edit 这将在 IE8 中触发警报 - 此警报在调用函数 ExecuteSearch 中。
http://jsbin.com/OdiSApI/2/edit 这似乎在 IE8 中运行良好。
注意:您需要点击右上角窗格中的Run with JS按钮。然后在下拉状态中的文本字段中输入一个城市并提交表单(这会调用 google maps geocode API)。
第二个链接中的“修复”如下:
//account for asynchronous nature of IE XDR request
//geo_location is undefined here in IE8
//this seems to fix ie8, though I'm not sure why...
var timeout = setTimeout(function() {
clearTimeout(timeout);
}, 10);
我遇到的问题是我不得不为 IE8-9 使用 XDomainRequest (XDR)(部分 CORS 支持)。在第一个 jsbin 中,我在 ExecuteSearch 函数中触发了警报,因为我的 GeoCode 函数在 xdr.onload 触发之前返回。
超时似乎在排队我的异步 XDR,但我不确定发生了什么以及为什么超时似乎是我的灵丹妙药。
有人有什么想法吗?
【问题讨论】:
-
看起来只是没有使用异步编程。任何这样的严重的黑客攻击都不能解决根本问题,并且会因浏览器而异,如果他们做任何事情的话。您不能在(就程序执行时间线而言)XDR 回调之前“返回 geo_location”!我建议只返回一个 Promise/A($.ajax 返回一个,可以包装 IE 的 XDR),然后正确使用异步(即回调)编程。
-
话虽如此,了解 IE8 实现以及为什么这样的虚拟超时会使其工作会有点有趣。请注意,
XDR.send仅在数据“发送”时保证同步,而不是返回数据(即仅在收到完整响应后调用 onload)。因此,与我之前的评论一样:我推荐 Promises/A 并继续使用异步模型(因此还要从普通 AJAX 中删除async: false)。 -
肯定在使用异步编程。 setTimeout 增加了 open() 和 send() 之间的时间。由于 XDR 对象被捕获到 setTimeout 闭包中,因此它可以更长时间地远离垃圾收集器。如果建立 HTTP 连接需要一段时间,send() 将需要更长的时间,因为它需要等待 open() 异步完成。当 send() 正在执行时,XDR 已经超出范围并且可以被垃圾收集。 setTimeout 使 XDR 对象保持更长的时间,使得 open() 更有可能在 send() 之前完成。
标签: javascript asynchronous internet-explorer-8 queue settimeout