Множественный вызов ссылочной функции (Callback must be a function. Received undefined)
Имеется следующий код:
function test () {
this.defaultCallback = {}
this.setCallback = function (callback) {
this.defaultCallback = callback
}
this.getDataIntervally = function () {
// get data
let data = 'baz'
setInterval(this.defaultCallback(data), 1000)
}
}
function bar (data) {
// do something with data
console.log(data)
}
let a = new test()
a.setCallback(bar)
a.getDataIntervally()
После инициализации экземпляра test в поле defaultCallback присваивается внешняя функция bar. Однако при попытке вызова в test функции getDataIntervally обращение к функции bar происходит только первый раз, остальные вызывают Exception.
Ниже лог:
baz // первый успешный вызов функции
node:internal/validators:224
throw new ERR_INVALID_CALLBACK(callback);
^
TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined
at setInterval (node:timers:210:3)
at testclass.foo (C:\Users\user\www\infocenterv2\test.js:9:9)
at Object.<anonymous> (C:\Users\user\www\infocenterv2\test.js:20:3)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
at node:internal/main/run_main_module:17:47 {
code: 'ERR_INVALID_CALLBACK'
}
Кто-то сталкивался с подобной ошибкой?
Ответы (1 шт):
setInterval(this.defaultCallback(data), 1000)
В такой конструкции в setInterval первым аргументом передаётся результат выполнения this.defaultCallback(data), а должна передаваться ссылка на функцию.
Делайте вот так:
function test() {
this.defaultCallback = undefined;
this.setCallback = (callback) => {
this.defaultCallback = callback;
};
this.getDataIntervally = () => {
let data = 'baz';
setInterval(() => this.defaultCallback(data), 1000);
};
}
function bar(data) {
console.log(`<bar> data="${data}"`);
}
let a = new test();
a.setCallback(bar);
a.getDataIntervally();
И используйте "стрелочные функции", чтобы не терять контекст.
Вопрос: сильно ли изменится код при использовании конструкции class с геттерами и сеттерами?
Ответ:
class Test {
#__defaultCallback;
get defaultCallback() {
return this.#__defaultCallback;
}
set defaultCallback(fn) {
this.#__defaultCallback = fn;
}
getDataIntervally() {
let data = 'baz';
setInterval(() => this.defaultCallback(data), 1000);
}
}
function bar(data) {
console.log(`<bar> data="${data}"`);
}
const a = new Test();
a.defaultCallback = bar;
a.getDataIntervally();