简体   繁体   English

singleton 与 js 导致 memory 泄漏

[英]singleton with js is causing memory leak

I'm developing a chrome extension, I want the config object, to be created once and shared between all parts of the application.我正在开发一个 chrome 扩展,我希望配置 object 被创建一次并在应用程序的所有部分之间共享。 A second object depending on the config should be also created once and shared.取决于配置的第二个 object 也应该创建一次并共享。 Each object contains promises.每个 object 都包含承诺。

function config () {
   this.instanse = null;
   this.status = 'pending';
   this.data = defualtData;
   
   // contructor
   this.init = async () => { 
     if(this.instanse) return this.instanse;
     this.instanse = this;
     await this.loadData(); 
   }

   this.loadData = async () => { // bring data from chrome store } 
}

and the second object as follow:第二个 object 如下:


function WebsitesClass (config) {
   this.instanse = null;
   this.status = 'pending';
   this.data = config.data.userProfile;
   
   // contructor
   this.init = async () => { 
     if(this.instanse) return this.instanse;
     this.instanse = this;
     await this.loadAnotherData(this.data); 
   }

   this.loadAnotherData = async () => { // bring data from chrome store; } 
}

then I instantiate the two objects at one file:然后我在一个文件中实例化这两个对象:


// init.js

const configObj = new Config();

export const hudConfigInit = () => {
    if (configObj.instance) return configObj;
    configObj.init();
    return configObj;
}


export const hudConfig = hudConfigInit();

const websitesObj = new WebsitesClass(hudConfig);

const hudWebsitesObjInit = () => {
    websitesObj.init();
    return websitesObj;
}

export const hudWebsites = hudWebsitesObjInit();

then I will import the created objects into all of my files, like:然后我会将创建的对象导入到我的所有文件中,例如:


import {hudConfig, hudWbsites} from 'init.js';

window.inload = async() => {

 await waitFor([ hudConfig, hudWebsites ]);

   // start work here ...

}

the problem is I'm facing a strange infinite loop somewhere in this implementation.问题是我在这个实现的某个地方面临一个奇怪的无限循环。

what did I do wrong?我做错了什么? any suggestions on this?对此有什么建议吗?

Edit编辑

I use this function to make sure that every function is loaded correctly:我使用这个 function 来确保每个 function 都正确加载:

/**
 * @summary detect when a single object finishes loading. 
 * @param {object} obj the object that we are waiting for 
 * @returns {boolean} true when the object finishes loading
 */
const finishWorking = async (obj) => {
    if (helpers.isFunction(obj.refresh)) {
        switch (obj.type) {
            case HUD_OBJECT_TYPES.hudConfig: { await hudConfig.refresh(); break; }
            case HUD_OBJECT_TYPES.hudWebsites: { await hudWebsites.refresh(hudConfig); break; }
            // case HUD_OBJECT_TYPES.hudSubscriptions: { await hudSubscriptions.refresh(hudConfig); break; }
        }
    }
    return new Promise(async (resolve, reject) => {
        while (obj.status !== workStatus.done) {
            await helpers.sleep(1000);
            // finishWorking(obj)
            /**  ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.infinite loop was here  **/

        }
        resolve(true);
    })
}

since it is a chrome extension:因为它是 chrome 扩展:

  1. sharing the object reference between the popup and the options page will create a copy for each of them since each of them is a separate document.在弹出窗口和选项页面之间共享 object 引用将为它们中的每一个创建一个副本,因为它们中的每一个都是一个单独的文档。
  2. trying to share object reference between the background and other components will cause an error, cause this kind of sharing is not allowed.试图在后台和其他组件之间共享 object 引用会导致错误,导致这种共享是不允许的。

the solution was:解决方案是:

  1. instantiate the object on the very top background page.在最顶部的背景页面上实例化 object。
  2. interact with that object using chrome.runtime.sendMessage() function, sending the right message and directing the response to the right object method.使用chrome.runtime.sendMessage() function 与 object 交互,发送正确的消息并将响应定向到正确的 object 方法。

so:所以:

// background.js

const configObj = new Config();

chrome.runtime.onMessage(async (req, sender, sendResponse)=>{
   switch(req.type){

    case "refreshConfig" : {
          await hudConfig.refresh();
          sendResponse(hudConfig.data);
         }
    }

})

also you can send a message from popup or options or content as:您也可以从弹出窗口或选项或内容发送消息:


 const refreshButton = document.querySelector('#save');

refreshButton.onClick(async() => {

  chrome.runtime.sendMessage({type: "refreshConfig"}, (data) =>{

      setData(data); //data is here the object after the update.
   })
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM