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