秒杀项目
秒杀项目基本环境搭建
商品展示模块
请求执行秒杀模块
秒杀流程总结

前台页面再次获取秒杀结果(MQ处理之后的)

分析:再次获取秒杀结果,获取的是消息队列处理后的结果,有可能秒杀成功,有可能秒杀失败,还有可能是发送请求了,但是消息队列的消息还没有被消费,这个时候,就需要轮询的调用获取秒杀结果的函数,我们可以通过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);
}