0

I have a jsnode class c with a constructor and several methods and I create an object by var example = new c(arguments);

One of the methods needs to access the object properties, I do so by using this. The method has function with the following code:

this.Busy=true;
console.log(this);   // outputs all the information of the object    
Promise.race([Promise.all(
    [asynchronousFunction("user1"),asynchronousFunction("user2"),asynchronousFunction("user3")],
        TimeoutFunction()])
    .then((output)=>{console.log(this);} // this is defined with all information here

And asynchronousFunction looks like this:

var asynchronousFunction= function(userToQuery) {
    console.log(this);  // undefined
    if(this.Busy===false) {
        return New Promise((resolve,reject) => {
            this.Busy=true;
            /* (this code uses promises; it checks the last time an object in the array (this.table) was updated, contacts the server asynchronously, updates the array and returns the result) */
        }
    }
}

The reason I have to check the array this.table is because the server is overloaded; it should only be queried depending on the timestamp of the data already fetched. How can I make sure the asynchronousFunction can modify the this of the object? I've tried bind, call and arrow functions with no result. I'm becoming desperate.

A-B
  • 31
  • 1
  • 6
  • 1
    Your code does not make a lot of sense. You are racing a single promise, what is that supposed to achieve? – Tomalak Oct 08 '17 at 12:16
  • 2
    If "*`this code uses promises`*" inside `new Promise`, you have the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it) which you should avoid! – Bergi Oct 08 '17 at 12:16
  • What array are you talking about? Please post the complete code – Bergi Oct 08 '17 at 12:16
  • 1
    Is `asynchronousFunction` a method of any object? Shouldn't it be a method of your class if you want to use `this.Busy`? However, if you want to use ´this.Busy` of your instance, the code doesn't make much sense, as you always set `Busy` to `true` already *before* calling the function. – Bergi Oct 08 '17 at 12:18
  • It is a plain function call to `asynchronousFunction()` that causes `this` to get lost. That's how Javascript works. Any plain function call resets `this`. You should probably just pass `this` as an argument to that function and use the argument instead of `this`. See [When you should pass this as an argument](https://stackoverflow.com/questions/28016664/when-you-pass-this-as-an-argument/28016676#28016676) for further explanation. – jfriend00 Oct 08 '17 at 12:56
  • I race two promises: the promise.all and a timeout. regarding promise constructor antipattern: the promise does other things; it prepares the data before returning it and it is supposed to update a this.table object. – A-B Oct 09 '17 at 13:21

2 Answers2

0

You can write var self = this; and after that change this to self:

var self = this;

//...

self.Busy=true;

//...

var asynchronousFunction= function(userToQuery) {
    console.log(self);  // undefined
    if(self.Busy===false) {
        return New Promise((resolve,reject) => {
            self.Busy=true;

        }
    }
} 
Maxim Shoustin
  • 77,483
  • 27
  • 203
  • 225
  • That's a good solution, but I guess that way the method can't modify the global object this.table. this.table is meant to be a mirror of the table stored in the server I'm querying; everytime the program needs data it checks the datetime of the last update, it queries the server if the data is old and then updates the global table. My aim was to have a method in the object that performed all these. – A-B Oct 09 '17 at 13:06
  • @AlfredoB saving `this` instance inside `self` is a good practice and developers use it widely. It will help you to avoid a lot of issues related to private scopes closures and so on – Maxim Shoustin Oct 09 '17 at 13:18
0

I have found a solution: Promise.race([Promise.all( [asynchronousFunction("user1").bind(this),asynchronousFunction("user2").bind(this),asynchronousFunction("user3").bind(this)], TimeoutFunction()])

update: it doesn't work. bind(this) only applies the this to the first function.

A-B
  • 31
  • 1
  • 6