摘要:靜下來(lái)想了想發(fā)現(xiàn)我犯了一個(gè)低級(jí)錯(cuò)誤。上面的代碼中函數(shù)是在這個(gè)函數(shù)閉包中申明的,在這個(gè)函數(shù)執(zhí)行完畢后,由于它被綁上了事件,引用并不為,所以沒(méi)有被回收。
最近寫(xiě)一個(gè)web應(yīng)用的圖片上傳功能,里面有這么個(gè)場(chǎng)景:點(diǎn)擊上傳按鈕,呼出file input框,選擇完圖片進(jìn)行前端壓縮然后上傳,完畢后將返回的圖片鏈接展示給用戶(hù)。這個(gè)功能很常見(jiàn),但是在這里卻翻了船,所以專(zhuān)門(mén)記錄一下這個(gè)bug。
我是這么寫(xiě)的(vue代碼片段):
methods: { clickInput(item, e) { this.uploadItem = e.target.parentNode; this.item = item; let input = this.input = this.uploadItem.querySelector("input"); async function changeHook() { let compress = new CompressImg({ maxSize: 500 * 1024, quality: 0.2, files: this.input.files, }) let blob = await compress.getBlob(); if (blob) { this.uploadImg(blob); } } input.removeEventListener("change", changeHook); input.addEventListener("change", changeHook); input.click(); }, }
此處寫(xiě)的很僵硬,直接在html中給input綁定事件即可,沒(méi)必要?jiǎng)討B(tài)綁定 捂臉
compressImg是參考網(wǎng)上大牛的方法用canvas的api進(jìn)行前端壓縮,具體見(jiàn)我的gist:https://gist.github.com/win5d...
為了防止綁定多個(gè)事件,這里先remove再add,看起來(lái)好像沒(méi)毛病,看了下控制臺(tái),發(fā)現(xiàn)上傳觸發(fā)了多次,excuse me?
回頭檢查了一下代碼,感覺(jué)沒(méi)毛病啊,開(kāi)始還以為是async函數(shù)惹的禍,改成普通函數(shù)發(fā)現(xiàn)還是有問(wèn)題。靜下來(lái)想了想發(fā)現(xiàn)我犯了一個(gè)低級(jí)錯(cuò)誤。
上面的代碼中changeHook函數(shù)是在clickInput這個(gè)函數(shù)(閉包)中申明的,在這個(gè)函數(shù)執(zhí)行完畢后,由于它被綁上了事件,引用并不為null,所以沒(méi)有被回收。下一次點(diǎn)擊時(shí)又回創(chuàng)建一個(gè)新的changeHook函數(shù),雖然都叫changeHook,但這兩個(gè)函數(shù)在不同的閉包之中,占據(jù)不同的內(nèi)存,調(diào)用removeEventListener也是然并卵,每次觸發(fā)clickInput都會(huì)造成一次內(nèi)存泄漏。
只需要把函數(shù)申明放到外面即可:
在函數(shù)里面申明函數(shù),這個(gè)寫(xiě)法我也知道很坑爹,由于這個(gè)函數(shù)只在這個(gè)方法用到,而且強(qiáng)迫癥不想在data里申明很多變量,偷懶不想處理參數(shù)傳遞,結(jié)果搞出這么個(gè)低級(jí)錯(cuò)誤。強(qiáng)迫癥得治,偷了的懶都得還,rua!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/89187.html
摘要:介紹瀏覽器的具有自動(dòng)垃圾回收機(jī)制,也就是說(shuō),執(zhí)行環(huán)境會(huì)負(fù)責(zé)管理代碼執(zhí)行過(guò)程中使用的內(nèi)存。中的內(nèi)存泄漏問(wèn)題程序的內(nèi)存溢出后,會(huì)使某一段函數(shù)體永遠(yuǎn)失效取決于當(dāng)時(shí)的代碼運(yùn)行到哪一個(gè)函數(shù),通常表現(xiàn)為程序突然卡死或程序出現(xiàn)異常。 showImg(https://segmentfault.com/img/remote/1460000018932880?w=4400&h=3080); 1. 介紹 瀏...
摘要:在運(yùn)行腳本時(shí),需要顯示的指定對(duì)象。大對(duì)象區(qū)每一個(gè)區(qū)域都是由一組內(nèi)存頁(yè)構(gòu)成的。這里是唯一擁有執(zhí)行權(quán)限的內(nèi)存區(qū)。換句話(huà)說(shuō),是該對(duì)象被之后所能回收到內(nèi)存的總和。一旦活躍對(duì)象已被移出,則在舊的半空間中剩下的任何死亡對(duì)象被丟棄。 內(nèi)存管理 本文以V8為背景 對(duì)之前的文章進(jìn)行重新編輯,內(nèi)容做了很多的調(diào)整,使其具有邏輯更加緊湊,內(nèi)容更加全面。 1. 基礎(chǔ)概念 1.1 生命周期 不管什么程序語(yǔ)言,內(nèi)存...
摘要:本系列的第一篇文章簡(jiǎn)單介紹了引擎運(yùn)行時(shí)間和堆棧的調(diào)用。編譯器將插入與操作系統(tǒng)交互的代碼,并申請(qǐng)存儲(chǔ)變量所需的堆棧字節(jié)數(shù)。當(dāng)函數(shù)調(diào)用其他函數(shù)時(shí),每個(gè)函數(shù)在調(diào)用堆棧時(shí)獲得自己的塊。因此,它不能為堆棧上的變量分配空間。 本系列的第一篇文章簡(jiǎn)單介紹了引擎、運(yùn)行時(shí)間和堆棧的調(diào)用。第二篇文章研究了谷歌V8 JavaScript引擎的內(nèi)部機(jī)制,并介紹了一些編寫(xiě)JavaScript代碼的技巧。 在這第...
閱讀 926·2021-10-27 14:14
閱讀 1751·2021-10-11 10:59
閱讀 1322·2019-08-30 13:13
閱讀 3157·2019-08-29 15:17
閱讀 2756·2019-08-29 13:48
閱讀 496·2019-08-26 13:36
閱讀 2088·2019-08-26 13:25
閱讀 863·2019-08-26 12:24