Вызов подпрограммы из обратного вызова setInterval выдает ошибку типа

javascript node.js typescript

54 просмотра

2 ответа

304 Репутация автора

Я новичок в JavaScript / TypeScript и пытаюсь выяснить, что здесь происходит.

class MyClass {

    constructor() {
        this.doThisEverySecond();
        setInterval(this.doThisEverySecond, 1000);  // Tried here
    }

    doThisEverySecond():void {
        console.log("Do some stuff");
        this.subroutineForOrganization();
        console.log("Do more stuff\n");
    }

    subroutineForOrganization():void {
        console.log("Doing many things");
    }
}

const foo:MyClass = new MyClass();
setInterval(foo.doThisEverySecond, 1000);  // And tried here

Я хочу вызвать функцию doThisEverySecond () и заставить ее выполняться каждые x секунд; и для простых организационных целей у меня есть кое-что из того, что он делает в подпрограмме subroutineForOrganization ().

Независимо от того, вызываю ли я setInterval () в его конструкторе или сразу после его создания, я получаю следующую ошибку:

Do some stuff
Doing many things
Do more stuff

Do some stuff
D:\Webstorm Projects\Sonification\es5\src_ts\test.js:8
        this.subroutineForOrganization();
             ^

TypeError: this.subroutineForOrganization is not a function
    at Timeout.MyClass.doThisEverySecond [as _repeat] (D:\Webstorm Projects\Sonification\es5\src_ts\test.js:8:14)
    at Timeout.wrapper [as _onTimeout] (timers.js:417:11)
    at tryOnTimeout (timers.js:224:11)
    at Timer.listOnTimeout (timers.js:198:5)

Process finished with exit code 1

Я не понимаю, почему он работает очень хорошо, когда вызывается из конструктора в первый раз, но затем имеет ошибку, когда его вызывают с setInterval. Как это функция тогда, но не сейчас? Есть ли какая-то волшебная область JavaScript, которую я не понимаю?

Спасибо!

Решено: вызов с помощью функции стрелки (как описано ниже) сохраняет ссылку на this( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Lexical_this )

Автор: davidlav Источник Размещён: 13.07.2016 10:11

Ответы (2)


-1 плюса

4 Репутация автора

Я считаю, что это потому, что вы не правильно определяете свои функции. Попробуйте это вместо этого:

function doThisEverySecond() {
    console.log("Do some stuff");
    this.subroutineForOrganization();
    console.log("Do more stuff\n");
}

А также:

function subroutineForOrganization() {
    console.log("Doing many things");
}
Автор: Skua Размещён: 13.07.2016 10:15

0 плюса

85227 Репутация автора

Используйте Function.prototype.bind функцию:

constructor() {
    this.doThisEverySecond();
    setInterval(this.doThisEverySecond.bind(this), 1000);  // Tried here
}
Автор: Nitzan Tomer Размещён: 13.07.2016 10:19
Вопросы из категории :
32x32