V
V
Vitaly2016-11-30 13:40:49
Node.js
Vitaly, 2016-11-30 13:40:49

How can you implement in JS waiting for the execution of asynchronous tasks when describing a class?

Good day everyone.
The question is how would you solve the problem with a constructor and asynchronous processes.
Example:

class Name {
     let self = this;
    constructor(data){
        this._init(data)
               .then(data=>{
                    self.init = data;
                    })
               .catch(console.error);
        }
    _init(data) { 
        return new Promise((resolve, reject) => {
            // искусственно создаем задержку, эмцлируя веб запрос:
            setTimeout(resolve, 2000, data);
            //resolve(data);
        })
     run(data) {
          rerurn data / this.init.
     }
    run2(data){
           let self = this;
           return new Promise((resolve, reject) => {
            resolve(data / self.init);
        })
     }
}

In the example above, when initializing, we do an asynchronous task, let's assume that it will take some time (request via http or something, that's not the point)
As an example:
let name = new Name(2);
console.log(name.run(6));
//или
name.run2(6).then(console.log).catch(console.error);

We expect to get 3, but we may not get it, since this.init may not have been received yet and the constructor is still running.
Who is struggling with this?
In my mind, and in practice, a crutch is implemented, a variable is a trigger, which symbolizes that the constructor has worked and if the trigger is not set, a delay is made, but I don’t like this approach, can anyone suggest a more elegant solution?
So far I have found the following solutions:
1. Through the factory:
class Engine {
    constructor(data) {
        this.data = data;
    }

    static makeEngine(pathToData) {
        return new Promise((resolve, reject) => {
            getData(pathToData).then(data => {
              resolve(new Engine(data))
            }).catch(reject);
        };
    }
}

Plus, I see that the object will be created only when the whole vermeland is executed, the minus is that the object will be the result of a promise and again either work with it in the generator for convenience, or in async. Well, or with hard trolling of all this stuff, write the main code after the timeout.
2. Through a specific constructor, I liked the idea, but I need to test it, plus use the 7th node with harmoni:
class Engine {

  constructor(path) {
    this.initialization = (async () => {
      this.resultOfAsyncOp = await doSomethingAsync(path)
    })()
  }

  async showPostsOnPage() {
    await this.initialization
    // actual body of the method
  }

}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Vitaliy, 2016-11-30
@vshvydky

He asked, he answered ....
the reception is curious, but not without questions, is it worth it to do so. There are criticisms of using a constructor to perform initialization methods. But with asynchronous tasks, it seemed acceptable to me.
Open to new ideas.

class Name {

    constructor(data) {
        console.log('constructor start');
        this.initialization = (async () => {
            this.init = await this._init(data)
        })();
        console.log('constructor end');
    }
    _init(data){
        return new Promise((resolve, reject)=>{
            console.log('_init');
            setTimeout(resolve, 2000, data);
        });
    }

    async run(data) {
        console.log('run start');
        await this.initialization;
        console.log('run end');
        return data / this.init;
    }
}

let name = new Name(2);
name.run(6).then(console.log).catch(console.error);

Result of work:
>node --harmony test2
constructor start
_init
constructor end
run start
run end
3

V
Vladimir, 2016-11-30
@Casufi

https://developer.mozilla.org/ru/docs/Web/JavaScri...
The function should return a promise
https://habrahabr.ru/company/mailru/blog/269465/

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question