亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

記一次低級(jí)并嚴(yán)重的開發(fā)失誤

wudengzan / 778人閱讀

摘要:而這一次的項(xiàng)目,原本以為開發(fā)挺順利的,但是開發(fā)完了,才發(fā)現(xiàn)自己犯了一個(gè)低級(jí)而嚴(yán)重的錯(cuò),這樣的一個(gè)失誤,我一直耿耿于懷。但是監(jiān)聽用戶退出頁(yè)面微信瀏覽器上面的那個(gè)返回或者關(guān)閉按鈕卻死活不行。也容易犯一些低級(jí)的錯(cuò)誤。

1.前言

前端從事了超過(guò)兩年,修復(fù)了無(wú)數(shù)的bug,寫了無(wú)數(shù)的bug;挖了很多次坑,填了很多次坑;犯了很多次錯(cuò),彌補(bǔ)了很多次,學(xué)習(xí)了很多次。一般而言,對(duì)于bug、坑,都是修復(fù)完了或者填完了,并且記住為什么會(huì)產(chǎn)生bug,為什么有坑,為什么犯錯(cuò),怎么解決的,下次怎么避免,就行了,就學(xué)習(xí)到了。而這一次的項(xiàng)目,原本以為開發(fā)挺順利的,但是開發(fā)完了,才發(fā)現(xiàn)自己犯了一個(gè)低級(jí)而嚴(yán)重的錯(cuò),這樣的一個(gè)失誤,我一直耿耿于懷。

2.起因

在3月9號(hào)的這一天,公司有個(gè)活動(dòng),希望用答題活動(dòng)推廣自己的小程序。結(jié)果因?yàn)殚_發(fā)時(shí)間太緊,小程序在3月5號(hào)才提審。在3月8號(hào)早上,小程序還沒(méi)有審核,在不得已的情況下,只能把答題活動(dòng)以網(wǎng)頁(yè)的形式進(jìn)行,使用vue開發(fā)。由于在3月9號(hào)要用到這個(gè)答題活動(dòng),所以3月8號(hào)必須要完成開發(fā),測(cè)試,驗(yàn)收。

開發(fā)的過(guò)程,都挺順利,只是把小程序的一些代碼,改成vue開發(fā)移動(dòng)端網(wǎng)站的方式,把標(biāo)簽換了,樣式稍微重寫一下,項(xiàng)目就跑起來(lái)了,至于一些交互邏輯,由于不能使用小程序的API,只能另找良方代替,但問(wèn)題基本不大。

麻煩的一個(gè)需求就是:當(dāng)用戶沒(méi)答完題中途退出的時(shí)候,要記錄用戶的答題狀態(tài)。比如答了哪些題目,哪些題目錯(cuò)了,哪些題目正確了,拿了多少分等數(shù)據(jù)。在小程序里面,很輕松可以利用生命周期函數(shù) unload() 進(jìn)行監(jiān)聽。當(dāng)用戶沒(méi)答完題退出頁(yè)面的時(shí)候,把用戶當(dāng)前的答題數(shù)據(jù),傳給后臺(tái),讓后臺(tái)進(jìn)行保存。在用戶下次進(jìn)入頁(yè)面的時(shí)候,我可以根據(jù)后臺(tái)返回的用戶答題狀態(tài),進(jìn)行信息的展示。如果用戶沒(méi)答過(guò)題目,就重新開始答題,如果用戶上次退出的時(shí)候,沒(méi)答完題目,就按照退出時(shí)的進(jìn)度,讓用戶重新答題,如果答完了題目,直接顯示答題結(jié)果頁(yè)面。

這個(gè)需求不難實(shí)現(xiàn),小程序有 onload() unload() 兩個(gè)生命周期函數(shù),只是在這兩個(gè)函數(shù)里面,調(diào)兩次接口而已。

但在網(wǎng)頁(yè)里面,監(jiān)聽用戶進(jìn)入頁(yè)面簡(jiǎn)單。但是監(jiān)聽用戶退出頁(yè)面(微信瀏覽器上面的那個(gè)‘返回’或者‘關(guān)閉’按鈕)卻死活不行。網(wǎng)上最多的解決方案是這個(gè),但是不知道是我使用方式有問(wèn)題還是人品問(wèn)題,壓根沒(méi)用,無(wú)論是微信開發(fā)者工具,還是安卓或者蘋果真機(jī)。

答案來(lái)自知乎:微信自帶瀏覽器環(huán)境內(nèi)左上角返回、關(guān)閉按鈕事件監(jiān)控?

pushHistory(); 
window.addEventListener("popstate", function(e) { 
    alert("我監(jiān)聽到了瀏覽器的返回按鈕事件啦");//根據(jù)自己的需求實(shí)現(xiàn)自己的功能 
}, false); 
function pushHistory() { 
    var state = { 
        title: "title", 
        url: "#"
    }; 
    window.history.pushState(state, "title", "#"); 
}

根據(jù)網(wǎng)上的方案,試了幾個(gè)(包括vue的生命周期函數(shù)),沒(méi)一個(gè)可行的。最后無(wú)奈之下,只能用一個(gè)蠢方法,用戶點(diǎn)擊每一題選項(xiàng)的時(shí)候,就把用戶當(dāng)前的記錄,通過(guò)接口發(fā)給后臺(tái),讓后臺(tái)記錄。這個(gè)就是我該文章說(shuō)的低級(jí)嚴(yán)重的失誤,想必大家也知道是怎么回事了。

3.失誤分析

這次的答題活動(dòng),一共有三輪,每輪10道題,現(xiàn)場(chǎng)大概有500人答題。本來(lái)使用小程序開發(fā),不管用戶是沒(méi)答題就讓用戶可以開始答題,答題途中退出就記錄狀態(tài),答完題就顯示結(jié)果。在這個(gè)過(guò)程中,我跟后臺(tái)交互的只有兩次:一次是用戶進(jìn)來(lái)的時(shí)候獲取用戶答題進(jìn)度,一次是用戶答完了最后一題,發(fā)送用戶成績(jī),讓后臺(tái)記錄;或者中途退出,發(fā)送用戶答題進(jìn)度給后臺(tái),讓后臺(tái)記錄。

但是后來(lái)我在網(wǎng)頁(yè)中,由于暫時(shí)沒(méi)法監(jiān)聽用戶是否退出,所以選擇了用戶回答完每一題的時(shí)候,把數(shù)據(jù)發(fā)給后臺(tái),讓后臺(tái)答題進(jìn)度。這樣請(qǐng)求數(shù)就多了N倍。服務(wù)器的壓力就大了很多。

由于用戶進(jìn)來(lái),無(wú)論是小程序還是網(wǎng)站,都要請(qǐng)求接口,獲取用戶答題數(shù)據(jù),這次不在對(duì)比范圍。這樣原本小程序只需要和后臺(tái)進(jìn)行一次握手,但是在網(wǎng)頁(yè)中,采用了不合適的方式,和后臺(tái)握手次數(shù)變成了10次。足足多了9倍。如果是500人,每一輪從原本的500次,變成了5000次,三輪就從原本的1500次,變成了15000次!一般而言,10道題選擇題,是兩分鐘左右的回答時(shí)間,就相當(dāng)于在2分鐘內(nèi)服務(wù)器要響應(yīng)的次數(shù)多了9倍,這個(gè)擔(dān)子突然重了很多。而已這些請(qǐng)求,基本都有沒(méi)什么意義的,因?yàn)榻^大部分的人,10道題,大概兩分鐘的答題時(shí)間里面,不會(huì)中途退出,相當(dāng)于我做了一件沒(méi)意義,又消耗服務(wù)器性能的事情。

讓我耿耿于懷的原因,我一向?qū)φ?qǐng)求數(shù)嚴(yán)格的控制,雖然現(xiàn)在公司不怎么考慮性能,服務(wù)器壓力。但是這會(huì)引起我的強(qiáng)迫癥。

4.解壓方案

由于答題活動(dòng),9號(hào)要使用,而我是8號(hào)晚上洗完澡的時(shí)候和同事聊天的時(shí)候才想起,所以我沒(méi)時(shí)間改了,因?yàn)楦牧艘彩切枰獣r(shí)間開發(fā),測(cè)試。9號(hào)由于同事請(qǐng)假,他的項(xiàng)目也由我負(fù)責(zé),也是比較趕的項(xiàng)目,我也沒(méi)那么多時(shí)間改。只能委屈一下服務(wù)器了。

說(shuō)是這樣說(shuō),但是關(guān)于其他的給服務(wù)器減輕負(fù)擔(dān)的方案,還是有比較講一下,算是給自己提個(gè)醒,也算是給大家提個(gè)醒。開發(fā)要注意一點(diǎn):不要急,不要急,不要急。

PS:當(dāng)時(shí)就是看著時(shí)間差不多是下午四點(diǎn)半了,然后還有兩個(gè)零散功能沒(méi)做,又要測(cè)試。找了很久的解決方案(監(jiān)聽微信的‘返回’或者‘關(guān)閉按鈕’)都沒(méi)下落的情況下,一下急了,腦袋放空,就想了那個(gè)方法。

cookie或者localstore

記錄用戶的狀態(tài),這個(gè)應(yīng)該是最好的解決方案了,也應(yīng)該是最簡(jiǎn)單的解決方案。

比如使用cookie記錄用戶的答題進(jìn)度。在用戶每答一題的時(shí)候,就把cookie記錄到的數(shù)據(jù),更新一次。這樣只需要在用戶答完了最后一題的時(shí)候再把用戶的成績(jī)發(fā)給后臺(tái)就好,至于用戶中途退出也沒(méi)有,根據(jù)cookie判斷就好,如果cookie有記錄到用戶的數(shù)據(jù)。就顯示上次用戶退出時(shí)候的題目,讓用戶繼續(xù)答題。

原代碼:
/**
* @dedependson 點(diǎn)擊選項(xiàng)
* @index 題目索引  number
* @item 當(dāng)前選項(xiàng)對(duì)象 object
*/
chooseDo(index,item){
    /*其他代碼略*/
    let _this=this;
    let _data={
        qid:_this.qid,//答題輪次,如"2"代表第二輪答題
        questions:_this.questions,//已答題目,"1,2,3"這個(gè)表示id為1,2,3的題目已經(jīng)回答了
        totalScore:_this.totalScore//當(dāng)前得分
    }
    //發(fā)送請(qǐng)求,讓后臺(tái)記錄用戶答題進(jìn)度
    this.$http.post(http_url.submit,_data,{emulateJSON:true}).then(res=>{
            
    })
}

然后再到頁(yè)面加載的時(shí)候

mounted(){
    this.$http.get(http_url.getQuestions,{
        params:{
            qid:this.qid
        }
    }).then(res=>{
        res=res.body;
        //如果請(qǐng)求成功
        if(res.code===0){
            //如果用戶沒(méi)答完題 0-沒(méi)開始答題 1-沒(méi)答完題   2-答完題目
            if(res.datas.status!==2){
                //獲取答題的題目
                this.questionList=res.datas.entryList;
                //如果題目小于10,就是開始答題了,但是沒(méi)答完(中途退出的原因)
                if(this.questionList.length<10){
                    //顯示答題頁(yè)面,讓用戶答題
                    this.questionListShow=true;
                }
                //否則就是沒(méi)答過(guò)題目,讓用戶答題
                else{
                    //顯示開始答題頁(yè)面(答題首頁(yè),用戶需要點(diǎn)擊開始答題)
                }
            }
            //如果用戶已經(jīng)答完題,顯示結(jié)果頁(yè)
            else{
                //代碼略
            }
        }
        else{
            alert(res.msg)
        }
    })
}
       
cookie方案
chooseDo(index,item){
    /*其他代碼略*/
    let _this=this;
    let _data={
        qid:_this.qid,//答題輪次,如"2"代表第二輪答題
        questions:_this.questions,//已答題目,"1,2,3"這個(gè)表示id為1,2,3的題目已經(jīng)回答了
        totalScore:_this.totalScore//當(dāng)前得分
    }
    //保存cookie一天
    //_this.qid作為答題輪次的標(biāo)識(shí)
    setCookie("answer-qid"+_this.qid,_this.qid,1);
    setCookie("answer-questions"+_this.qid,_this.questions,1);
    setCookie("answer-totalScore"+_this.qid,_this.totalScore,1);
}    

cookie函數(shù)參考:ec-do

//設(shè)置cookie
setCookie(name, value, iDay) {
    let oDate = new Date();
    oDate.setDate(oDate.getDate() + iDay);
    document.cookie = name + "=" + value + ";expires=" + oDate;
},
//獲取cookie
getCookie(name) {
    let arr = document.cookie.split("; "),arr2;
    for (let i = 0; i < arr.length; i++) {
        arr2 = arr[i].split("=");
        if (arr2[0] == name) {
            return arr2[1];
        }
    }
    return "";
},
//刪除cookie
removeCookie(name) {
    this.setCookie(name, 1, -1);
}, 

然后再到頁(yè)面加載的時(shí)候,處理方式的改變。

mounted(){
    this.$http.get(http_url.getQuestions,{
        params:{
            qid:this.qid
        }
    }).then(res=>{
        res=res.body;
        //如果請(qǐng)求成功
        if(res.code===0){
            //如果用戶沒(méi)答完題 0-沒(méi)開始答題 1-沒(méi)答完題   2-答完題目
            if(res.datas.status!==2){
                //記錄答題輪次
                this.qid=res.datas.qid; 
                //獲取答題的題目
                this.questionList=res.datas.entryList; 
                //如果用戶中途退出,我們沒(méi)有和后臺(tái)對(duì)接口,后臺(tái)無(wú)法記錄用戶答題進(jìn)度,所以這次請(qǐng)求,返回的結(jié)果要么是沒(méi)開始答題,要么是答完題了。
                //要還原用戶答題記錄,要使用cookie
                //如果存在cookie記錄,那么用戶肯定是至少答過(guò)一題,還原用戶答題進(jìn)度
                let _answerQid=getCookie("answer-qid"+this.qid)
                _answerQuestions=getCookie("answer-qid"+this.qid).split(",");
                //字符串轉(zhuǎn)整數(shù)
                _answerQuestions.map(item=>+item);
                
                if(_answerQid&&_answerQuestions){
                    this.questionList.fifler(item=>{
                        //item.id是題目的id
                        //如果題目的id存在,就過(guò)濾掉
                        _answerQuestions.indexOf(item.id)===-1
                    });
                    //顯示答題頁(yè)面,讓用戶答題
                    this.questionListShow=true;  
                }
                //否則就是沒(méi)答過(guò)題目,讓用戶答題
                else{
                    //顯示開始答題頁(yè)面(答題首頁(yè),用戶需要點(diǎn)擊開始答題)
                }
            }
            //如果用戶已經(jīng)答完題,顯示結(jié)果頁(yè)
            else{
                //代碼略
            }
        }
        else{
            alert(res.msg)
        }
    })
}

代碼上面,可能用了 cookie 會(huì)復(fù)雜些,但是就多了幾行而已,差不了多少,反倒是減輕了很多請(qǐng)求。

在小程序沒(méi)有使用這個(gè)方案,就是考慮到用戶退出小程序,可能會(huì)清除緩存,雖然這個(gè)幾率不大,所以使用生命周期函數(shù)進(jìn)行unload()進(jìn)行監(jiān)聽,用戶退出就把用戶答題進(jìn)度提交給后臺(tái),讓后臺(tái)記錄,這樣的情況不會(huì)很多,甚至沒(méi)有,請(qǐng)求不會(huì)很多,所以當(dāng)時(shí)就用了這個(gè)方案。沒(méi)有使用cookie或者localstore。

注意幾點(diǎn):

1.無(wú)論什么情況,開發(fā)都需要一個(gè)清醒的頭腦,因?yàn)轭^腦不清醒,寫的都是bug,那個(gè)活動(dòng)是一個(gè)一次性的項(xiàng)目,如果是長(zhǎng)期的,我肯定會(huì)重構(gòu)的,因?yàn)楫?dāng)時(shí)寫的代碼太爛了。也容易犯一些低級(jí)的錯(cuò)誤。

2.不要為了小概率的事件想得太多,給自己,同事,服務(wù)器都帶來(lái)麻煩,也影響項(xiàng)目進(jìn)度。這次就是想得太多,結(jié)果提測(cè)的時(shí)間晚了,驗(yàn)收的時(shí)間晚了,自己也犯了錯(cuò)誤。想太多的后果可能就是撿了芝麻,漏了西瓜,甚至是偷雞不成蝕把米。

小結(jié)

這次的的失誤就告一段落了,我也總結(jié)了一下,自己為什么會(huì)對(duì)這次失誤更更于懷。

1.最近一直在看怎么優(yōu)化代碼,讓代碼更有可讀性,可維護(hù)性。卻犯了請(qǐng)求數(shù)過(guò)多的錯(cuò)。顧此失彼啊。

2.第二個(gè)就是因?yàn)檫@次失誤,導(dǎo)致的后果太嚴(yán)重了,直接多了90%的請(qǐng)求。以往失誤導(dǎo)致的后果沒(méi)怎么嚴(yán)重。

3.以往犯錯(cuò)的時(shí)候,在項(xiàng)目上線之前能夠發(fā)現(xiàn),并且有時(shí)候改,這次不一樣,這次是發(fā)現(xiàn)了,但是沒(méi)時(shí)間改了。

4.那些以為不會(huì)有,不應(yīng)該犯的錯(cuò)??赡芫驮陬^腦不清醒的時(shí)候,就會(huì)犯這些錯(cuò)誤,無(wú)論什么時(shí)候都得留個(gè)神,這次也算是我自己提醒自己了。

不過(guò)結(jié)局是還算是好的,當(dāng)天因?yàn)闀r(shí)間關(guān)系,答題活動(dòng)沒(méi)有進(jìn)行,所以服務(wù)器沒(méi)有受到考驗(yàn)。如果當(dāng)天服務(wù)器承受不住壓力,崩了,我也可能要引咎辭職了!

好了,故事就是這樣了,有點(diǎn)日記的感覺(jué),希望大家諒解下。如果文章有什么地方寫錯(cuò)了,也歡迎指點(diǎn)交流。

--------------------華麗的分割線-------------------

想了解更多,關(guān)注關(guān)注我的微信公眾號(hào):守候書閣

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/93350.html

相關(guān)文章

  • 一次頁(yè)面卡頓排查

    摘要:記一次頁(yè)面卡頓排查前述前段時(shí)間上線的一個(gè)移動(dòng)端的項(xiàng)目,由于開發(fā)時(shí)間倉(cāng)促,一直被用戶投訴頁(yè)面卡頓。這顯然要導(dǎo)致卡頓??偨Y(jié)這只是頁(yè)面卡頓的一個(gè)點(diǎn),當(dāng)然還有很多,我們的頁(yè)面卡頓就是由這樣一個(gè)一個(gè)的點(diǎn)造成的。 記一次頁(yè)面卡頓排查 前述 前段時(shí)間上線的一個(gè)移動(dòng)端的項(xiàng)目,由于開發(fā)時(shí)間倉(cāng)促,一直被用戶投訴頁(yè)面卡頓?,F(xiàn)在終于有時(shí)間來(lái)好好排查一下,看到底是什么原因。業(yè)務(wù)代碼都不是自己寫的,這是頗為頭疼的...

    Lin_YT 評(píng)論0 收藏0
  • 聽說(shuō)拼多多因漏洞被薅了200億?- 談?wù)勡浖y(cè)試

    摘要:昨天看到一個(gè)大新聞拼多多在日凌晨出現(xiàn)漏洞,用戶可以領(lǐng)元無(wú)門檻優(yōu)惠券。拼多多本來(lái)就是家爭(zhēng)議頗大的公司,這次事件更是引發(fā)輿論熱議。有人估計(jì)全球?yàn)榇嘶ㄙM(fèi)的相關(guān)費(fèi)用有數(shù)億美元。軟件發(fā)布測(cè)試版讓用戶使用,就屬于一種黑盒測(cè)試。 昨天看到一個(gè)大新聞: 拼多多在20日凌晨出現(xiàn)漏洞,用戶可以領(lǐng)100元無(wú)門檻優(yōu)惠券 。一夜之間,被黑產(chǎn)、羊毛黨和聞?dòng)嵍鴣?lái)的吃瓜群眾薅了個(gè)底朝天,直到第二天上午9點(diǎn)才將優(yōu)惠券下...

    henry14 評(píng)論0 收藏0
  • 你可能不知道 npm 實(shí)用技巧

    摘要:但這并不意味著依賴版本是鎖死的。黃色表示不符合指定的語(yǔ)義化版本范圍,比如大版本升級(jí),升級(jí)可能會(huì)遇到兼容性問(wèn)題。文件可以列出不想打包的文件,避免把一些無(wú)關(guān)的文件發(fā)布到上。 作者: LeanCloud weakish 分享一些 npm 包管理工具的實(shí)用小竅門,希望能夠略微提高下前端、Node.js 開發(fā)者的生活質(zhì)量。 絕大多數(shù)前端和 Node.js 開發(fā)者每天的日常工作都離不開 npm,不...

    NickZhou 評(píng)論0 收藏0
  • 面對(duì)大規(guī)模系統(tǒng)工程,看Facebook如何處理故障排查(一)

    摘要:當(dāng)奧巴馬贏得美國(guó)總統(tǒng)大選時(shí),頁(yè)面活躍度刷新了記錄。對(duì)于每一個(gè)成因,都應(yīng)制定相應(yīng)的預(yù)防措施,以減輕大規(guī)模事故。這種故障會(huì)通過(guò)許多層面進(jìn)入系統(tǒng)服務(wù)中,導(dǎo)致系統(tǒng)故障的發(fā)生。 作者介紹:Ben Maurer是Facebook的網(wǎng)絡(luò)基礎(chǔ)團(tuán)隊(duì)的技術(shù)領(lǐng)先者,主要負(fù)責(zé)整個(gè)Facebook面向用戶產(chǎn)品的性能和可靠性。Ben于2010年正式加入Facebook,基礎(chǔ)設(shè)施團(tuán)隊(duì)的成員。在加入Facebook之...

    scola666 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<