1

I know this question has been asked multiple times (yes, I did some research) but I can't see to find a solution that fits my needs.

What I have done so far:

I was building a function that tracked the percentage of how far the user scrolled down a page and display this nicely into some progressbar. This worked perfectly but when I opened the developer console on Chrome and looked at the Timeline tab (this displays what is being run in a nice graphic), I realised that my code was quite "active". It ran every pixel the user scrolled down the page, which is quite alot to be honest.

So I thought to myself, how can this be improved and I have come up with a solution that involves executing a function only once per {whatever} milliseconds. This involves a variable set to true or false, if the function has already been executed in the {whatever} milliseconds.

What i want to accomplish:

I want to be able to set a reference to an external variable that will act as a flag to determine if the function has already been executed or not.

function qeue(fn, interval, status){ // this function name might not be very fitting..
    // fn = function to be executed
    // interval = function can only run once between the intervals

    // status = tricky part.. 
    // This should contain a reference to an external variable that is either true or false 
}

How can this be accomplished?

side note

If this explanation isn't helping, and you still don't get what I want:

How can I pass a reference to a variable into a function, so that function can act based on the value of that variable?

Why normal parameters are not an option I want to implement some sort of recursive setTimeout functionality inside a function, that checks if another function has been executed or not, if I pass this in to a parameter, this parameter cannot change during the process.

Hope you guys can help me out!

Thank you

Thank you for all your great answers. You made me learn alot. I am going with the debounce strategy! I marked T.J. Crowder as the best answer, because it was a good explanation and one of the first. But thank you all once again!

Gerrit Luimstra
  • 522
  • 6
  • 23
  • 2
    http://stackoverflow.com/a/4298672 – Teemu Jan 01 '17 at 15:13
  • you could waterfall promises so you can use the last result in each further settimeout call. Check this post https://remysharp.com/2015/12/18/promise-waterfall/#comment-3076688933 – Sebas Jan 01 '17 at 15:13

5 Answers5

2

What you've described wanting to do doesn't immediately say "use a reference to a variable" to me (as Teemu points out, sounds like you want debouncing), but answering your question about references to variables...

JavaScript doesn't have any form of references to variables (other than through closures, which might be problematic here). But you can readily do what you're talking about by just using an object and using a property on it. The property is the "variable."

Simple example:

function foo(obj) {
  var counter = 0;
  var timer = setInterval(function() {
    console.log("foo: " + obj.property);
    if (++counter === 5) {
      clearInterval(timer);
    }
  }, 500);
}

var o = {property: "unchanged"};
// Give the "reference" to `property` to `foo`:
foo(o);

// Update it periodically while `foo` is doing its asynchronous thing
setTimeout(function() {
  o.property = "update 1";
}, 1000);
setTimeout(function() {
  o.property = "update 2";
}, 1700);
Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

In JavaScript values such as integers, strings, etc. are passed by value. If you want to pass a reference, you have to pass an object into the JavaScript function. (JavaScript objects are passed by reference)

function adjustValues(referenceObject) {
    referenceObject.foo = 2;
    referenceObject.bar = "newValue";
}

referenceObject = {
  foo: 1,
  bar: "initialValue"
};

adjustValues(referenceObject);
0

why don't you use the setInterval function, it will do exactly what you want.

Example:

setInterval(function() { 
    // logic to be implemented
}, delayInMilliseconds)
0

How can this be accomplished?

Not with a variable. There are no "references to variables" in JS. I can see two simple solutions:

  1. pass a getter/setter function:

    function queue(getStatus) {
        …
        getStatus() // gets current value
        …
    }
    
    var executed = false;
    queue(function() { return executed; });
    
  2. pass an object with a property:

    function queue(status) {
         …
        status.executed // gets current value
        …
    }
    
    var status = {executed: false};
    queue(status);
    

I have come up with a solution that involves executing a function only once per {whatever} milliseconds. This involves a variable set to true or false, if the function has already been executed in the {whatever} milliseconds.

I cannot see the reason why this variable would need to be a parameter to the function, and be available (or even settable?) outside it. Just use a local variable inside queue.

Btw, this functionality is known as debouncing, you don't have to write this yourself. Many implementations are already available on the web, sometimes as part of larger libraries. See for example What does _.debounce do?.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

Try the following example :

'use strict';

var observable = 0;

function incObservable() {
 ++observable;
 console.log('incObservable observable: '+observable);
}
function observe() {
 console.log('observe observable: '+observable);
}

var observer = setInterval(observe, 100);

setTimeout(function() {
 incObservable();
 setTimeout(function() {
  incObservable();
  setTimeout(function() {
   incObservable();
  }, 300);
 }, 300);
}, 300);

setTimeout(function() {
 // Stop obsever
 clearInterval(observer);
}, 1000);

// observe observable: 0
// observe observable: 0
// incObservable observable: 1
// observe observable: 1
// observe observable: 1
// observe observable: 1
// incObservable observable: 2
// observe observable: 2
// observe observable: 2
// observe observable: 2
// incObservable observable: 3
// observe observable: 3
Roge
  • 94
  • 1
  • 7