Интервал угловой установки неправильно работает внутри цикла for

#javascript #angular #typescript #setinterval

Вопрос:

Я хочу вызвать API с динамическим интервалом. Но когда я попытался использовать приведенный ниже фрагмент кода , он работает, но интервал времени работает неправильно.Мне нужно провести динамический короткий опрос. Версия : Угловая 7

 ngOnInit() {
    this.liveFunction();
}

liveFunction() {
    var list = [{
        "id": 1,
        "timer": 10000,
        "url": "https://www.sampleurl.com/1"
    },
    {
        "id": 2,
        "timer": 20000,
        "url": "https://www.sampleurl.com/users/1"
    }];
    for (var i = 0, len = list.length; i < len; i  = 1) {
        (function (i) {
            setInterval(function () {
                this.invokeAPI(list[i].url)
            }, list[i].timer)
        })(i);
    }
}

invokeAPI (url) {
    //do stuff 
}
 

Ответ №1:

Для этого вам придется реализовать логику асинхронного ожидания. Попробуй это:

 async ngOnInit() {
    await this.liveFunction();
}

async liveFunction() {
    var list = [{
        "id": 1,
        "timer": 10000,
        "url": "https://www.sampleurl.com/1"
    },
    {
        "id": 2,
        "timer": 20000,
        "url": "https://www.sampleurl.com/users/1"
    }];
    for (var i = 0, len = list.length; i < len; i  = 1) {
        (function (i) {
            setInterval(function () {
                this.invokeAPI(list[i].url)
            }, list[i].timer)
        })(i);
    }
}

invokeAPI (url) {
    //do stuff 
}
 

Ответ №2:

Вы теряете область действия при использовании function операторов, взгляните:

     for (var i = 0, len = list.length; i < len; i  = 1) {
        (function (i) { // "this" keyword now refers to this function, it doesn't have "invokeApi" method
            setInterval(function () { // and here "this" becomes another function without the method you need
                this.invokeAPI(list[i].url)
            }, list[i].timer)
        })(i);
    }
 

Лучшим решением является использование функций со стрелками:

       for (var i = 0, len = list.length; i < len; i  = 1) {
          ((i: number) => {
            setInterval(() => {
                this.invokeAPI(list[i].url);
            }, list[i].timer)
          })(i);
      }
 

Рабочий пример: https://stackblitz.com/edit/angular-hvkkas?файл=src/приложение/app.component.ts

В качестве альтернативы вы можете сохранить «это» в переменной, чтобы вызвать метод из другой области:

     const _self = this;
    for (var i = 0, len = list.length; i < len; i  = 1) {
        (function (i) {
            setInterval(function () {
                _self.invokeAPI(list[i].url)
            }, list[i].timer)
        })(i);
    }