国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【debug】事件綁定代碼中的一個低級錯誤導致的內存泄漏

XboxYan / 1966人閱讀

摘要:靜下來想了想發現我犯了一個低級錯誤。上面的代碼中函數是在這個函數閉包中申明的,在這個函數執行完畢后,由于它被綁上了事件,引用并不為,所以沒有被回收。

最近寫一個web應用的圖片上傳功能,里面有這么個場景:點擊上傳按鈕,呼出file input框,選擇完圖片進行前端壓縮然后上傳,完畢后將返回的圖片鏈接展示給用戶。這個功能很常見,但是在這里卻翻了船,所以專門記錄一下這個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綁定事件即可,沒必要動態綁定 捂臉

compressImg是參考網上大牛的方法用canvas的api進行前端壓縮,具體見我的gist:https://gist.github.com/win5d...

為了防止綁定多個事件,這里先remove再add,看起來好像沒毛病,看了下控制臺,發現上傳觸發了多次,excuse me?

回頭檢查了一下代碼,感覺沒毛病啊,開始還以為是async函數惹的禍,改成普通函數發現還是有問題。靜下來想了想發現我犯了一個低級錯誤。

上面的代碼中changeHook函數是在clickInput這個函數(閉包)中申明的,在這個函數執行完畢后,由于它被綁上了事件,引用并不為null,所以沒有被回收。下一次點擊時又回創建一個新的changeHook函數,雖然都叫changeHook,但這兩個函數在不同的閉包之中,占據不同的內存,調用removeEventListener也是然并卵,每次觸發clickInput都會造成一次內存泄漏。

只需要把函數申明放到外面即可:




在函數里面申明函數,這個寫法我也知道很坑爹,由于這個函數只在這個方法用到,而且強迫癥不想在data里申明很多變量,偷懶不想處理參數傳遞,結果搞出這么個低級錯誤。強迫癥得治,偷了的懶都得還,rua!

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/89187.html

相關文章

  • JS垃圾回收與內存泄漏

    摘要:介紹瀏覽器的具有自動垃圾回收機制,也就是說,執行環境會負責管理代碼執行過程中使用的內存。中的內存泄漏問題程序的內存溢出后,會使某一段函數體永遠失效取決于當時的代碼運行到哪一個函數,通常表現為程序突然卡死或程序出現異常。 showImg(https://segmentfault.com/img/remote/1460000018932880?w=4400&h=3080); 1. 介紹 瀏...

    xiaolinbang 評論0 收藏0
  • 【前端進階之路】內存基本知識

    摘要:在運行腳本時,需要顯示的指定對象。大對象區每一個區域都是由一組內存頁構成的。這里是唯一擁有執行權限的內存區。換句話說,是該對象被之后所能回收到內存的總和。一旦活躍對象已被移出,則在舊的半空間中剩下的任何死亡對象被丟棄。 內存管理 本文以V8為背景 對之前的文章進行重新編輯,內容做了很多的調整,使其具有邏輯更加緊湊,內容更加全面。 1. 基礎概念 1.1 生命周期 不管什么程序語言,內存...

    Simon_Zhou 評論0 收藏0
  • JavaScript如何工作:內存管理+如何處理4個常見內存泄漏

    摘要:本系列的第一篇文章簡單介紹了引擎運行時間和堆棧的調用。編譯器將插入與操作系統交互的代碼,并申請存儲變量所需的堆棧字節數。當函數調用其他函數時,每個函數在調用堆棧時獲得自己的塊。因此,它不能為堆棧上的變量分配空間。 本系列的第一篇文章簡單介紹了引擎、運行時間和堆棧的調用。第二篇文章研究了谷歌V8 JavaScript引擎的內部機制,并介紹了一些編寫JavaScript代碼的技巧。 在這第...

    anRui 評論0 收藏0

發表評論

0條評論

XboxYan

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<