文本将以一个具体的案例介绍在前端开发中如何建立模型去协调复杂的竞态条件
竞态条件介绍
复杂问题场景
demo地址
功能简述
- 在地图中展示不同
聚合级别的业务数据。
- 地图级别分为
1~20级,级别数值越大当前地图的比例尺越小。
- 地图不同级别展示不同级别聚合的数据,比如
1~6级展示按行政省聚合的数据,7~12级展示按行政市聚合的数据,13~20级展示行政区县聚合的数据。
- 用户选择了
专题图层,时根据当前地图的聚合级别请求相应聚合级别的聚合数据,并且在地图中渲染。
- 获取
行政省,行政市级别聚合的数据时,加上数据更新时间的查询条件,获取行政区县级别聚合的数据时还要额外加上城市过滤条件。
- 当用户进行地图的缩放时,如果需要展示的数据的
聚合级别改变了则加载相应的数据并渲染。
竞态条件分析
- 用户选择了一个
专题图层后,触发数据的获取。比如当前地图级别为6级,此时应该异步获取按照行政省级别聚合的数据。如果获取按照行政省级别聚合数据的请求得到响应之前,用户就切换到地图7级,此时应该请求按行政市级别聚合的数据。如果用户停留在地图7级时,获取按照行政省级别聚合数据的请求得到响应了,此数据不应该在界面被渲染出来。
细节功能点
- 用户选择了一个
专题图层后,触发数据的获取。比如当前地图级别为6级,此时应该异步获取按照行政省级别聚合的数据。如果获取按照行政省级别聚合数据的请求得到响应之前,用户就切换到地图7级,并且又切回到地图6级,也不应该重复请求按照行政省聚合的数据。
- 当用户取消选中了一个
专题图层时,获取这个专题图层数据的仍在pending状态的请求应该被cancel。
问题思考
- 这里的异步请求的请求条件是不确定的
- 比如请求按照
行政省级别聚合的数据时查询字段可能是
{
keyWord,
time,
adminLevel,
}
{
keyWord,
time,
adminLevel,
city,
}
- 同一时刻处于pengding状态的异步请求的个数是不确定的
- 如果异步请求得到响应了,但是界面当前的状态和触发请求时使用的状态不一致时,数据不应该被丢弃。否则用户在地图
6级和7级之间来回切换时,地图可能永远不会渲染出来数据。
- 所以不能用这种方式来简单的去协调竞态条件
ArticleStore.fetch(id).then((article) => {
if (this.props.articleID !== id) return;
this.setState({
title: article.title,
body: article.body
});
});
建立模型
具体实现
data-cacher