显示模块内的计时器(回调)更新 public 属性

Timer (callback) inside a revealing module to update public property

我正在尝试让回调在模块内部工作以更新 属性。在这种情况下,我只希望它切换 属性 值,并希望能够在外部看到它。

这是简单的模块

var Module = (function () {


    // private
    var isLoaded=false;
    var timer = null;

    var _privateMethod = function () {
        console.log('hello from private')
    }

    //public
    var publicMethod = function(){
        console.log('in public method')
        _privateMethod();
    }

    var start = function(){
        console.log('starting timer')
        timer = setInterval( function() {
            console.log('timer callback')
            isLoaded = !isLoaded;
        },1000)
    }

    var stop = function(){
        console.log('stopping timer')
        clearInterval(timer)
    }

    return {
        publicMethod: publicMethod,
        isLoaded: isLoaded,
        start: start,
        stop: stop,
    }

})();

module.exports = Module;

我正在用这个

测试它
function sleep(milliseconds) {
    var start = new Date().getTime();
    for (var i = 0; i < 1e7; i++) {
      if ((new Date().getTime() - start) > milliseconds){
        break;
      }
    }
  }

var DM = require('./module.js')

DM.publicMethod()
DM.start()

console.log(DM.isLoaded)
 sleep(500)

console.log(DM.isLoaded)
 sleep(500)

console.log(DM.isLoaded)
 sleep(500)

console.log(DM.isLoaded)
 sleep(500)

 DM.stop();

它没有抛出错误,看起来它启动计时器没问题,但我从来没有从回调中获得输出并且 属性 没有更新。我猜它是范围问题,但我不能指手画脚。

要做到这一点(使用一般结构),您有两个选择:

保留对象

保留对对象的引用 return:

var obj;

// ...

obj = {
    publicMethod: publicMethod,
    isLoaded: false,
    start: start,
    stop: stop,
};
return obj;

...并删除 isLoaded 变量,而是在回调中设置 obj.isLoaded = true

实例:

var Module = (function() {
    var obj;
    var timer = null;

    var start = function(){
        console.log('starting timer')
        timer = setInterval( function() {
            console.log('timer callback')
            obj.isLoaded = !obj.isLoaded;
        },1000)
    };

    var stop = function(){
        console.log('stopping timer')
        clearInterval(timer)
    };
    
    obj = {
        //publicMethod: publicMethod,
        isLoaded: false,
        start: start,
        stop: stop,
    };
    return obj;
})();
Module.start();

var t = setInterval(function() {
  console.log("Module.isLoaded = " + Module.isLoaded);
}, 500);
setTimeout(function() {
  console.log("Stopping");
  clearInterval(t);
  Module.stop();
}, 10000);
.as-console-wrapper {
  max-height: 100% !important;
}

使用访问器属性:

这具有只读的优点:

return {
    publicMethod: publicMethod,
    get isLoaded() {
        return isLoaded;
    },
    start: start,
    stop: stop,
};

实例:

var Module = (function() {
    var isLoaded = false;
    var timer = null;

    var start = function(){
        console.log('starting timer')
        timer = setInterval( function() {
            console.log('timer callback')
            isLoaded = !isLoaded;
        },1000)
    };

    var stop = function(){
        console.log('stopping timer')
        clearInterval(timer)
    };
    
    obj = {
        //publicMethod: publicMethod,
        get isLoaded() {
            return isLoaded;
        },
        start: start,
        stop: stop,
    };
    return obj;
})();
Module.start();

var t = setInterval(function() {
  console.log("Module.isLoaded = " + Module.isLoaded);
}, 500);
setTimeout(function() {
  console.log("Stopping");
  clearInterval(t);
  Module.stop();
}, 10000);
.as-console-wrapper {
  max-height: 100% !important;
}