2015-07-17 2 views
0

Я пытаюсь выполнить функцию каждый час. Это существенно проверяет документы из MonoDB. Тем не менее, во время первого интервала сбой приложения метание следующее сообщение об ошибке:NodeJS setInterval таймер сбой после первого интервала

timers.js:252 
callback.apply(this, args); 
     ^ 

TypeError: Cannot call method 'apply' of undefined 
    at wrapper [as _onTimeout] (timers.js:252:14) 
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15) 

Вот отрывки из моих файлов:

валидатора

function validate() { ... } 

module.exports = { 
    validate : validate 
} 

WWW

var validator = require('../lib/validator'); 
var app = require('../app'); 

app.listen(3000, function() { 
    setInterval(validator.validate(), 360000); 
} 

ответ

5

setInterval() принимает ссылку метод. Вам только нужно удалить скобки, откуда вы передаете в функцию обратного вызова:

setInterval(validator.validate, 360000);

По существу, второй раз интервал выстреливает он будет пытаться вызвать результат первого вызова для проверки() вместо сама функция, таким образом, ошибка. Вот подобный тест на стороне клиента JavaScript (setInterval ведет себя точно так же, насколько мне известно):

function setTime() { 
 
    $('#currentDateTime').html(new Date()); 
 
} 
 

 
$(function() { 
 
    setInterval(setTime, 1000); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<div id="currentDateTime"></div>

ТАКЖЕ В качестве интересного только в случае, если к этому ответу, я нашел другого пользователя, который, кажется, правильно передает ссылку на метод, но получает аналогичную ошибку. Комментарий предполагает, что, возможно, может быть верхняя граница для того, чтобы время ожидания было удалено (размер int? Signed int? Just guessing).

Node.js crashes when using long interval in setinterval

+0

Это интересно, потому что я пробовал тот же подход в ** файле app.js **, который давал тот же результат. Но поскольку он перемещается внутри 'app.listen() {...}', он работает нормально. Я думаю, это может быть потому, что у меня были другие таймеры, такие как 'setImmediate()'. Тем не менее, мне все равно хотелось бы знать, будет ли 'setInterval()' в моем случае запускать событие один раз при запуске приложения, а затем на каждом заданном интервале – wshaheer

+0

Если я что-то не хватает, я считаю, что реализация setInterval() одинакова между клиента и узла. Я бы проверил тест, в котором вы только передаете ссылку на метод, и используйте очень быстрый таймер, чтобы увидеть, стреляет ли он как запрограммированный.Мне было бы интересно узнать, действительно ли реализация Node действительно отличается, но не имеет большого смысла, что интервал будет использовать результат вашего вызова метода против ссылки при вызове в период времени. –

2

Вы неправильно вызываете setInterval ... он должен быть завернут в свою собственную область функций.

app.listen(3000, function() { 
 
    setInterval(function() { validator.validate() }, 360000); 
 
}

+3

Или даже просто 'setInterval (validator.validate, 3600000)' – Phil

1

Попробуйте следующий фрагмент кода.

app.listen(3000, function() { 
    setInterval(validator.validate.bind(validator), 360000); 
} 

setInterval принимает функцию в качестве первого параметра, и ваш фрагмент кода вызывает validator.validate() немедленно (и я полагаю, что вызов функции не возвращает функцию).

+0

Да, он просто работает с документами в db и обновляет его статус – wshaheer

Смежные вопросы