处理JavaScript中的某种异步情况

时间:2017-08-03 06:23:02

标签: javascript asynchronous

想象一下,我有这样的设置。想象一下,我的页面上有一些地图,旁边有一个对话框,其中有一个切换按钮。

  • 想象一下,当用户点击切换按钮时,会向服务器发送不同的请求(取决于切换状态)(根据请求返回不同类型的地图数据)。如果在收到有关餐馆的说明数据后点击切换,下次点击它会收到有关医院的数据等。

  • 还可以想象,当用户拖动地图时,会向服务器发送刷新信号,该服务器会发送相同类型的数据但具有更新的信息。例如,如果用户在地图上显示医院时拖动地图,则会再次收到医院,但会更新位置。

问题

想象一下两种情况:

  • 假设用户多次快速点击切换 - 然后会发生以下事情。首先,发送请求以接收餐馆数据。但餐馆数据尚未到达 - 现在收到餐馆数据之前,下一个切换点击发生,并发送请求以获取医院数据(通常第二次点击切换将删除餐馆数据,但因为它不在地图,它不能)。因此,最终我们将在地图上找到餐馆和医院数据,这是我们不想要的。

  • 想象一下,用户点击切换并发送请求以接收餐馆数据。但是收到餐馆数据之前想象用户拖动地图(导致刷新)。由于拖拽现在发生的情况是,由于刷新,目前地图上有医院数据,将发送更新医院数据的请求。最后,我们将再次在地图上找到医院和餐馆的数据。

我希望你能看到我在这里遇到的那种问题的模式。 处理此类情况的最佳做法是什么?

2 个答案:

答案 0 :(得分:3)

我心中有解决方案。一个对用户体验和UI有影响,另一个涉及发送最后一个请求。我将解释如何:

<强> 1。在请求完成之前禁用地图和按钮。

所以你可以做的是一个加载或重叠div,它一直存在,直到返回请求信息。在此之前,不允许用户使用地图或切换。这是UI影响,但我看到网站的行为方式。

<强> 2。地图位置。 另一种选择是将地图位置存储在类似的本地存储中,并在请求成功时再次匹配地图位置。如果地图位于不同的位置,请在此区域中提供“搜索”等消息.Google地图的行为方式与此类似。

第3。提供最新的ajax请求并中止其他人:

这可以通过按队列/顺序推送请求并发送最后一个来获得响应来完成。比如你是通过ajax来迎合它,所以有些代码如下面的代码,如果我打电话给 getFoo 10次,最后一个会被解雇

var ajax = null;
var getFoo = function() {
    if(ajax) ajax.abort();
    ajax= $.ajax({});
};

答案 1 :(得分:1)

你所描述的是一个简单的竞争条件。

这类问题没有一般解决方案,需要逐案处理。但在大多数情况下,您可能希望显示用户已完成的最新操作的结果。如果您没有其他方式知道哪个请求是哪个,您可以在请求中附加某种标识符,例如GUID,并且只在相应请求完成时显示数据。< / p>

有时,解决方案可以简单地禁用在请求期间可能导致竞争条件的所有操作,但这会恶化用户体验。以Google Docs在线编辑器为例,想象一下每次触发自动保存功能时整个编辑器都会被禁用。在这种情况下,存储每个更新并从这些操作组成状态将是有益的。执行状态管理的JavaScript之一是Redux。如果要存储这样的数据,可以使用数据库,例如EventStore