怎么感覺(jué)web倒計(jì)時(shí)交互不該像老師這樣寫,我感覺(jué)這樣不太合適,難道我的想法錯(cuò)誤?
關(guān)于課程:
《Java高并發(fā)秒殺API之web層》
怎么感覺(jué)web倒計(jì)時(shí)交互不該像老師這樣寫,我感覺(jué)這樣不太合適,難道我的想法錯(cuò)誤?
一、controller里的 /time/now 這個(gè)方法完全沒(méi)有必要,獲取秒殺地址Exposer里就包含了當(dāng)前系統(tǒng)時(shí)間
下面看Exposer的屬性:
public?class?Exposer?{ //?是否要暴露的,表示是否開(kāi)啟秒殺 private?boolean?exposed; //?md5加密措施 private?String?md5; //?秒殺的id private?long?seckillId; //?系統(tǒng)當(dāng)前時(shí)間?毫秒 private?long?now; //?秒殺開(kāi)始時(shí)間?毫秒 private?long?start; //?秒殺結(jié)束時(shí)間?毫秒 private?long?end; .......
倒計(jì)時(shí)交互流程我覺(jué)得應(yīng)該是下面這樣:
在詳情頁(yè)jsp通過(guò)“/{seckillId}/exposer"直接獲取這個(gè)Exposer 的封裝json對(duì)象SeckillResult<Exposer>。
判斷exposed屬性,
1.如果是false,則拿now分別比較start和end,如果在start前面則開(kāi)始倒計(jì)時(shí),如果在end后面則顯示秒殺結(jié)束。
2.如果是true,則處于秒殺有效時(shí)間內(nèi),顯示秒殺按鈕。
獲取的Exposer對(duì)象中的數(shù)據(jù),已經(jīng)是服務(wù)端執(zhí)行了業(yè)務(wù)邏輯才放入的,直接可以拿來(lái)用。我不明白為什么jsp里還要寫這么多邏輯,jsp最大的作用只是用來(lái)展示。而且對(duì)于以后維護(hù)也不方便,需要服務(wù)端和客戶端都要改。
二、另外關(guān)于異常處理,我也感覺(jué)不合理。比如在SeckillController的方法executeSeckill中:
try?{????? SeckillExecution?execution?=?seckillService.executeSeckill(seckillId,?userPhone,?md5); return?new?SeckillResult<SeckillExecution>(true,execution);???? }catch?(RepeatkillException?e){???? SeckillExecution?execution?=?new?SeckillExecution(seckillId,?SeckillStateEnum.REPEAT_KILL);???? return?new?SeckillResult<SeckillExecution>(false,execution);???? }catch?(SeckillCloseException?e){???? SeckillExecution?execution?=?new?SeckillExecution(seckillId,?SeckillStateEnum.END);???? return?new?SeckillResult<SeckillExecution>(false,execution);???? }catch?(Exception?e){???? logger.error(e.getMessage(),e);???? SeckillExecution?execution?=?new?SeckillExecution(seckillId,?SeckillStateEnum.INNER_ERROR);???? return?new?SeckillResult<SeckillExecution>(false,execution);???? }
catch到異常就應(yīng)該把秒殺失敗的標(biāo)志,以及錯(cuò)誤信息返回給前段就行了,為什么是SeckillResult<SeckillExecution>(false,execution); ?其中false我可以理解,但是execution有什么用,SeckillResult不是有(boolean success, String error)的構(gòu)造器嗎?一個(gè)String的信息就行,需要傳對(duì)象過(guò)去嗎?
三、還有SeckillResult的boolean success,SeckillExecution 的?int state,Exposer的boolean exposed;我覺(jué)得概念設(shè)計(jì)的很混亂,老師講解的也不是很清楚。
我認(rèn)為,SeckillResult有boolean success和String error表示是否執(zhí)行成功和異常信息就好,Exposer的boolean exposed表示秒殺是否開(kāi)啟。SeckillExecution 的?int state完全沒(méi)有必要,枚舉應(yīng)該用在異常類里(可以給父類SeckillException加一個(gè)state的屬性),這些信息只會(huì)在秒殺失敗的時(shí)候返回給前段,直接捕捉異常,得到異常的message以字符轉(zhuǎn)返回就行了,秒殺失敗的時(shí)候根本不需要返回SeckillResult對(duì)象。
感覺(jué)有些混亂和冗余。
以上只是我個(gè)人的一些想法,希望大家可以看一下我想的對(duì)不對(duì),如果有不對(duì)指正。如果本課的老師可以看到,真誠(chéng)希望可以解疑,拜謝。
另外:
這是我參考老師的代碼,按照自己的理解寫的seckil.js邏輯代碼,我感覺(jué)這樣更好理解一些,經(jīng)測(cè)試可以實(shí)現(xiàn)功能。
//存放主要的交互邏輯js代碼 //javaScript模塊化,可以模擬java的分包。 //seckill?對(duì)象有屬性?URL(URL本身可能還有別的屬性),屬性也可以為函數(shù),因?yàn)樵趕cript中函數(shù)也是對(duì)象。 //調(diào)用方法類似:seckill.detail.init(params); var?seckill?=?{ //?:(冒號(hào))對(duì)象表達(dá)法?冒號(hào)在這里用來(lái)分割對(duì)象的屬性和屬性值。 //?秒殺相關(guān)ajax的url URL?:?{ nowUrl?:?function?()?{ return?'/seckill/seckill/time/now'; }, exposerUrl?:?function?(seckillId)?{ return?"/seckill/seckill/"?+?seckillId?+?"/exposer"; }, seckillUrl?:?function?(seckillId,?md5)?{ return?"/seckill/seckill/"?+?seckillId?+?"/"?+?md5?+?"/execution"; } }, //?校驗(yàn)手機(jī)號(hào) validatePhone?:?function?(phone)?{ //?if(phone){}表示不為空,isNaN(phone)表示非數(shù)字 if?(phone?&&?phone.length?==?11?&&?!isNaN(phone))?{ return?true; }?else?{ return?false; } }, seckillView?:?function?(seckillId)?{ $ .post( seckill.URL.exposerUrl(seckillId),?{}, function?(result)?{ if?(result?&&?result['success'])?{?//?請(qǐng)求成功 var?exposer?=?result['data']; var?seckillId?=?exposer['seckillId']; var?seckillBox?=?$('#seckill-box'); if?(exposer['exposed'])?{?//?可以秒殺 var?md5?=?exposer['md5']; var?killUrl?=?seckill.URL.seckillUrl( seckillId,?md5); seckillBox .html('<button?class="btn?btn-primary?btn-lg"?id="killBtn">開(kāi)始秒殺</button>');?//?按鈕 //?綁定點(diǎn)擊事件(綁定一次) $("#killBtn") .one( 'click', function?()?{ //?執(zhí)行秒殺的請(qǐng)求操作 $(this).addClass( 'disabled'); //?發(fā)送秒殺的請(qǐng)求 $ .post( killUrl,?{}, function?( result)?{ if?(result ?&&?result['success'])?{ var?seckillExecution?=?result['data']; var?state?=?seckillExecution['state']; var?stateInfo?=?seckillExecution['stateInfo']; //?顯示秒殺結(jié)果 seckillBox .html('<span?class="label?label-success">' ?+?stateInfo ?+?'</span>'); } }) }) }?else?{?//?不可以秒殺 var?now?=?exposer['now']; var?start?=?exposer['start']; var?end?=?exposer['end']; if?(now?<?start)?{?//?還未開(kāi)始?倒計(jì)時(shí) seckill.countdown(seckillId,?now, start,?seckillBox); }?else?{?//?已經(jīng)結(jié)束(exposed為false只能是未開(kāi)始或者結(jié)束) seckillBox.html('秒殺結(jié)束'); } } }?else?{?//?請(qǐng)求失敗 console.log("result:"?+?result); } }) }, //?倒計(jì)時(shí)處理 countdown?:?function?(seckillId,?now,?start,?seckillBox)?{ //?計(jì)時(shí)事件綁定 var?killTime?=?new?Date(Number(start)?+?1000);?//?加一秒的時(shí)間偏移。(運(yùn)算計(jì)時(shí)的消耗時(shí)間,后來(lái)細(xì)想應(yīng)該是減去消耗時(shí)間,但是因?yàn)闊o(wú)法知道消耗的時(shí)間多少,減多了會(huì)提前顯示出點(diǎn)擊按鈕,并不合理,所以最好不加不減。) //?jquery倒計(jì)時(shí)插件,監(jiān)聽(tīng)時(shí)間變化循環(huán)回調(diào)函數(shù) seckillBox.countdown(killTime,?function?(event)?{ //?格式化時(shí)間 var?format?=?event.strftime('秒殺計(jì)時(shí):?%D天??%H小時(shí)??%M分鐘??%S秒'); //?更新倒計(jì)時(shí)節(jié)點(diǎn)組件 seckillBox.html(format); }).on('finish.countdown',?function?()?{?//?倒計(jì)時(shí)結(jié)束的回調(diào)函數(shù) //?倒計(jì)時(shí)結(jié)束,以防倒計(jì)時(shí)誤差,需要重新請(qǐng)求exposer,判斷是否已經(jīng)開(kāi)始,來(lái)顯示秒殺按鈕或者更正倒計(jì)時(shí) seckill.seckillView(seckillId); }); }, //?詳情頁(yè)秒殺邏輯 detail?:?{ //?詳情頁(yè)初始化 init?:?function?(params)?{ //?******1。手機(jī)驗(yàn)證和登錄,2。計(jì)時(shí)交互 //?*******規(guī)劃我們的交互流程 //?利用jquery的cookie插件在cookie中查找手機(jī)號(hào) var?killPhone?=?$.cookie('killPhone'); //?訪問(wèn)參數(shù)中對(duì)應(yīng)的數(shù)據(jù)(javascript的訪問(wèn)方式) var?seckillId?=?params['seckillId']; var?startTime?=?params['startTime']; var?endTime?=?params['endTime']; //?驗(yàn)證手機(jī)號(hào) if?(!seckill.validatePhone(killPhone))?{?//?未登錄 //?獲取彈出層對(duì)象 var?killPhoneModal?=?$("#killPhoneModal"); //?顯示彈出層 killPhoneModal.modal({ show?:?true,?//?顯示彈出層 backdrop?:?'static',?//?禁止位置關(guān)閉 keyboard?:?false //?關(guān)閉鍵盤事件 }); //?為手機(jī)號(hào)的提交按鈕綁定點(diǎn)擊事件 $('#submitPhone') .click( function?()?{ //?獲取用戶輸入的手機(jī)號(hào) var?inputPhone?=?$('#killPhone').val(); //?提交的電話號(hào)碼有效 if?(seckill.validatePhone(inputPhone))?{ //?電話寫入cookie //?{expires:7,path:'/seckill'}表示這個(gè)cookie的有效期為7天, //?只有訪問(wèn)本域名下/seckill路徑才會(huì)在request中帶上這個(gè)數(shù)據(jù)到cookie $.cookie('killPhone',?inputPhone,?{ expires?:?7, path?:?'/seckill' }) //?刷新頁(yè)面 window.location.reload(); }?else?{?//?提交的電話號(hào)碼無(wú)效 //?顯示手機(jī)號(hào)輸入錯(cuò)誤的提示信息(先隱藏節(jié)點(diǎn),再寫入數(shù)據(jù),再顯示出來(lái),添加緩慢出現(xiàn)的顯示效果) $('#killPhoneMessage') .hide() .html( '<label?class="label?label-danger">手機(jī)號(hào)錯(cuò)誤!</label>') .show(500); } }); } //?已經(jīng)登錄 seckill.seckillView(seckillId); } } }
2016-09-19
一,用/time/now可以減輕服務(wù)器負(fù)擔(dān),exposer還得每一秒都查詢數(shù)據(jù)庫(kù)
其余不知道
2016-09-11
這是我參考老師的代碼,按照自己的理解寫的邏輯代碼,我感覺(jué)這樣更好理解一些,經(jīng)測(cè)試可以實(shí)現(xiàn)功能。