分析:再次獲取秒殺結果,獲取的是消息隊列處理后的結果,有可能秒殺成功,有可能秒殺失敗,還有可能是發送請求了,但是消息隊列的消息還沒有被消費,這個時候,就需要輪詢的調用獲取秒殺結果的函數,我們可以通過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);
}