你可能来这里是为了谴责我,但这是一个真实的用例。
在线教育领域,有SCORM课程。我必须在网站上使用旧的SCORM课程。 SCORM课程是“基于Web的”并在浏览器中运行,但是他们希望在iframe中运行,并且他们希望父级提供GetValue方法和SetValue。
所以这些SCORM课程正在做一些事情,比如parent.SetValue(“得分”,“90”)并继续前进。如果有任何问题,该函数应该返回“false”。
SCORM来自90年代,在现代网络中,我们知道我们必须做回调/承诺,http经常“失败”。您可能认为解决方案是SetValue,它写入本地数据,然后尝试重试直到它完成,但SCORM课程通常设置为仅在SetValue工作时移动到下一个屏幕,因此您不应该放弃除非SetValue实际保存在服务器上,否则用户前进。
TL; DR
假设同步请求是必需的,那么正确的方法是什么?
到目前为止,我知道$.ajax({async:false ...
,但现在浏览器警告这一点,听起来他们只是忽略了你的同步请求。我想也许使用websockets或web worker或者某种东西是在现代编程中做同步请求的正确方法。但我不知道如何提出这样的要求。我不允许更改SCORM课程的代码(它们是用各种课程制作工具生成的)
为了澄清,我完全控制了SetValue函数的实现。
$.ajax({async:false ...
会长期工作吗? (5 - 10年)
注意:在此用例中完全冻结UI直到请求成功或失败完全可以接受。这就是课程所假设的。
答案 0 :(得分:5)
到目前为止,我知道
$.ajax({async:false…
,但现在浏览器警告
这是正确的方法(如果你使用的是jQuery),它会发送一个同步的XMLHttpRequest。只是忽略警告。这是一个警告,你使用过时的技术,你已经知道了。
听起来他们只会忽略你的同步请求。
这不太可能。
我在考虑使用websockets或web worker,或者某些东西是在现代编程中执行同步请求的正确方法。
不,websockets和web worker总是异步的,你不能使用它们来使你的异步请求看起来是同步的(实际上没有任何东西可以让你这样做)。
$.ajax({async:false…
会长期工作吗? (5 - 10年)
我们无法知道(并且SO不是水晶球)。它可能,特别是在旧浏览器中,或者它可能不会。浏览器供应商不愿意破坏运行Web的功能的兼容性,并且仍然需要不时的同步请求。在某些时候,太少(重要)的网页将使用它(<1%,<1‰,无论他们决定什么门槛),浏览器最终会有信心将其删除。那时,您的企业将意识到弃用这些过时的课程制作工具。
答案 1 :(得分:3)
根据我对学习管理系统的经验,答案是:伪造它。
您写道:
在此用例中完全冻结UI直到请求成功或失败完全可以接受。那是课程的假设。
也许您的课程会假设这一点,但在过去十年中我使用的任何学习管理系统都不是这种情况。
从我所看到的情况来看,学习管理系统不会使用同步请求,因为它们会阻止其他脚本,这会给页面/课程被锁定或损坏的印象。解决方法是通过抽象层(包括SCORM API)使用异步调用,并将'true'
返回到课程,即使您无法验证AJAX调用实际上是否成功。
LMS如何处理SCORM数据的高级视图:
当课程启动时,LMS从数据库中获取所有课程的现有SCORM数据,然后将其放入客户端的JavaScript对象(可通过SCORM API访问)。当您通过SCORM获取数据时,通常会获取此预加载的JS对象中的数据 - 您无法直接从数据库获取实时响应。因此,使用SCORM的API.GetValue
时不需要AJAX。
当您尝试API.SetValue
时,您最初将键/值对存储在JS对象中,而不是SCORM数据库中。因此,客户端 JS对象需要同步指示它是否成功存储了数据('true'
)或不存在('false'
)。数据库 - 和AJAX - 在您尝试使用API.Commit()
将数据持久化数据库之前不会发挥作用。
当您尝试从调用AJAX的API.Commit()
获取成功值时,大多数LMS都会伪造它。他们会做一个异步请求,以确保课程不会被打破,因此从Commit()
返回的值几乎总是'true'
。它不可靠。