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

时间:2018-04-26 17:03:00

标签: javascript callback setinterval revealing-module-pattern

Im attempting to get a callback working inside a module in order to update a property. In this case I just want it to toggle the property value, and would like to be able to see that externally.

Here is the simple module

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;

and im testing it with this

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();

It doesnt toss an error, and it looks like its starting the timer ok but im never getting the output from the callback and the property isnt updating. Im guessing its a scope issues, but I cant put my finger on it.

1 个答案:

答案 0 :(得分:1)

要执行此操作(使用该常规结构),您有两个选择:

保留对象

保留对您返回的对象的引用:

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;
}