обратные вызовы постепенно увеличиваются с установленным методом Interval JavaScript - PullRequest
1 голос
/ 22 октября 2019

Я выполняю следующий сценарий и обратные вызовы из XHR-запроса постепенно увеличиваются (1, 2, 3 ..... и т. Д.), Но сетевой вызов происходит только один раз.

class Service {

    profiles = [] //assume array contains objetcs
    xhr = new XMLHttpRequest();
    token = null;

    constructor(token) {
        this.xhr = new XMLHttpRequest();
        this.token = token
    }

    setInterval(res => {this.doFunc()}, 10000);

    doFunc() {
       if (this.profiles.length > 3) {
          this.doChoice(this.profiles[0]).then(response => {
              console.log(response); //printing only onetime
          });
       }
    }

    async doChoice(profile) {
        return await new Promise(resolve => {
            this.like(profile.id, response => {
                //code below is excuting gradually with interval method
                console.log('Liked');
                console.log(profile);
                this.profiles.splice(this.profiles.indexOf(profile), 1);
                resolve(JSON.parse(response));
            });
        })
    }

    like(id, subscribe = {res: ''}) {
        let url = 'https://someurl/' + id;

        this.xhr.open("GET", url);
        this.xhr.setRequestHeader("x-auth-token", this.token);
        this.xhr.addEventListener("readystatechange", function () {
            //code below is excuting gradually with interval method
            if (this.readyState === 4 && this.status === 200) {
                if (this.responseText) {
                    console.log(this.responseText); 
                    subscribe(this.responseText);
                }
            }
        });
        this.xhr.send();
    }
}

Если кто-то может объяснить мне, что я здесь делаю неправильно, это было бы здорово!

1 Ответ

1 голос
/ 22 октября 2019

Не храните XMLHttpRequest как свойство. Вместо этого создавайте его каждый раз, когда вам нужно / нужно отправить запрос конечной точке.

Кроме того, код может быть значительно упрощен:

class Service {
    constructor(token) {
        this.token = token;
        this.profiles = [];
    
        setInterval(this.doFunc.bind(this), 10000);
    }
    doFunc() {
       if (this.profiles.length > 3) {
          this.doChoice(this.profiles[0]).then(profile => {
              console.log('Liked');
              console.log(profile);
              this.profiles.splice(this.profiles.indexOf(profile), 1);
          });
       }
    }
    doChoice(profile) {
        return new Promise((resolve, reject) => {
            let url = 'https://someurl/' + profile.id;
            let xhr = new XMLHttpRequest();
            
            xhr.open("GET", url);
            xhr.setRequestHeader("x-auth-token", this.token);
            xhr.addEventListener("readystatechange", function () {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    resolve(xhr.responseText);
                } else {
                  reject(new Error('XMLHttpRequest failed'));
                }
            });
            xhr.send();
        });
    }
}

Как уже указывал @HereticMonkey, вы также не должны использовать setInterval вне методов класса, потому что (а) это кажется невероятно странным и (б)он выполняет побочный эффект (в вашем случае действительно несколько побочных эффектов), просто импортируя класс.

...