Статьи

Дети, всегда помните, чтобы очистить ваши интервалы

Создание поддельных демо-графиков всегда весело. Здесь вы делаете график без данных, генерируете случайные точки данных, пытаетесь сделать его максимально реалистичным.

Два дня назад у меня не получилось.

Звучит просто, правда? Чтобы создать случайный график, вы генерируете случайные данные. Что-то вроде этого:

var data = _.range(250).map(function () {
    return Math.round(Math.random()*100);
});

И ваш график будет выглядеть так:

Полностью случайный граф

Ну, это не выглядит реалистично. Сумасшедшие шипы, глубокие долины … если бы система реального мира вела себя так, вы бы очень беспокоились за ее благополучие. Это не подходит для демонстрации.

И кроме того, вы все равно хотели получить живой график.

Таким образом, вы перемещаете генерацию данных в бэкэнд и подключаете его с помощью socket.io . Затем вы создаете функцию, которая генерирует один элемент данных каждый 250ms.

Генерация данных выглядит следующим образом:

io.on('connection', function (socket) {
    setInterval(function () {
        socket.emit('cpu', update());
    }, 250);
 
    function update() {
        return Math.round(Math.random()*100);
    }
});

Ваш график теперь выглядит так:

Перемещение случайного графа

Ура! Это движется!

Но все еще слишком случайно, чтобы выглядеть реалистично. Процессор , который ведет себя как то серьезные неприятности!

Что если вместо создания случайных значений мы произвели случайные изменения существующих значений? Это может сработать. Запомните предыдущее состояние, внесите небольшое случайное изменение.

Генерация данных теперь выглядит так:

io.on('connection', function (socket) {
    var previous = 0;
 
    setInterval(function () {
        previous = update(previous);
        socket.emit('cpu', previous);
    }, 250);
 
    function (previous) {
        previous += Math.random()*10-5;
        if (previous > 100) previous = 100;
        if (previous < 0) previous = 0;
 
        return Math.round(previous);
    }
});

И график выглядит так:

Фиксированный случайный граф, 1

Фиксированный случайный граф, 1

Или вот так:

Фиксированный случайный граф, 2

Фиксированный случайный граф, 2

Или даже так:

Фиксированный случайный граф, 3

Фиксированный случайный граф, 3

Чего ждать? Это даже хуже, чем раньше! Как это возможно, изменения значений на каждом шаге крошечные ?

И я разрушил мой мозг и разрушил мой мозг, а затем разрушил мой мозг еще немного. Обновлял страницу много раз. Переписал функцию генерации данных много раз. Ничто из того, что я пробовал, не сработало. График выглядел более спорадическим, чем когда-либо.

Можете ли вы определить ошибку?

Подсказка лежит в тех графиках, которые движутся быстрее и быстрее с каждым обновлением. Что-то дурацкое происходит — неочищенный setInterval.

Вы видите, что процесс backend node.js является постоянным. Интервал в 250 миллисекунд не исчезает, когда вы обновляете страницу. О нет, он все еще там, ждет тебя, преследует свою добычу, охотится.

И так как socket.io делает все возможное, чтобы быть более надежным, чем нет, он будет повторно подключать старые сокеты, потому что, эй, у вас, вероятно, просто пятнистый Wi-Fi. Но мы также начали новое setIntervalна каждом connectionмероприятии.

Да уж.

Это не единственная случайная функция, которая ведет себя забавно, это целая куча!

Если мы исправим бэкэнд-код так:

io.on('connection', function (socket) {
    var previous = 0;
 
    var interval = setInterval(function () {
        previous = update(previous);
        socket.emit('cpu', previous);
    }, 250);
 
    function (previous) {
        previous += Math.random()*10-5;
        if (previous > 100) previous = 100;
        if (previous < 0) previous = 0;
 
        return Math.round(previous);
    }
 
    socket.on('disconnect', function () {
        clearInterval(interval);
    });
});

The graph looks like this:

Перемещение графика, хорошо

Moving graph, good

And all is right in the world.

You’re happy, your boss is happy, your graph looks like it could be real but isn’t. Acting.