分析:再次获取秒杀结果,获取的是消息队列处理后的结果,有可能秒杀成功,有可能秒杀失败,还有可能是发送请求了,但是消息队列的消息还没有被消费,这个时候,就需要轮询的调用获取秒杀结果的函数,我们可以通过window.setInterval方法实现,该方法对应的clearInterval可以终止轮询,但是需要将setInterval的返回值ID作为参数,所以我们需要定义一个全局变量接收setInterval的返回值。
1. 在15-seckill-web的模块的seckill.js中的execSeckill函数中轮询调用再次获取秒杀结果的queryResult函数
//处理响应结果
if(rtnMessage.errorCode == 1){
//秒杀成功,已经下单到MQ,返回中间结果 可以做动画处理
$("#seckillTip").html("<span style='color:red;'>"+ rtnMessage.errorMessage +"</span>");
//接下来再发送一个请求获取最终秒杀的结果(轮询,每3秒查一次)
seckillObj.timeFlag = window.setInterval(function(){
seckillObj.func.queryResult(id)
},3*1000);
}else{
//秒杀失败 展示失败信息
$("#seckillTip").html("<span style='color:red;'>"+ rtnMessage.errorMessage +"</span>");
}
2. 在15-seckill-web的模块的seckill.js中编写queryResult函数
//查询最终秒杀结果
queryResult:function (id) {
$.ajax({
url: seckillObj.url.resultURL() +id,
type:"post",
dataType:"json",
success:function (rtnMessage) {
if(rtnMessage.errorCode == 1){
//秒杀成功
$("#seckillTip").html("<span style='color:blue;'>"+ rtnMessage.errorMessage +"</span>");
//终止轮询
window.clearInterval(seckillObj.timeFlag);
}else if(rtnMessage.errorCode == 0){
//秒杀失败
$("#seckillTip").html("<span style='color:blue;'>"+ rtnMessage.errorMessage +"</span>");
//终止轮询
window.clearInterval(seckillObj.timeFlag);
}else{
//3秒后,依然没有查询到结果,那么需要3秒后,继续发送请求获取秒杀结果,我们这里不需要做什么
}
}
});
}
3. 在15-seckill-web的seckill.js的url属性中定义resultURL
resultURL:function () {
return seckillObj.contextPath +"/seckill/result/";
}
4. 在15-seckill-web的GoodsController中处理获取最终秒杀结果的请求
@PostMapping("/seckill/result/{id}")
public @ResponseBody ReturnObject result(@PathVariable("id") Integer id){
ReturnObject returnObject = new ReturnObject();
//在Redis中暂时没有查询到结果
returnObject.setErrorCode(2);
//用户再次查询,肯定处于登录状态,可以从session获取用户信息(我们这里省略了用户登录)
String resultJSON = redisTemplate.opsForValue().get(Constants.REDIS_RESULT + id + ":" + "888888");
return StringUtils.isEmpty(resultJSON)?returnObject : JSONObject.parseObject(resultJSON,ReturnObject.class);
}