Отправка периодических сердцебиений, интересно, если есть какие-либо ошибки таймера


Что?

heartbeatjs Это небольшой облегченный библиотека, которая помогает вам выполнять периодические сердцебиения функции и определяет тайм-ауты, когда они происходят, запустив событий.

Он в основном предназначен для TCP/IP соединения, но вы можете использовать его с любым протоколом вы хотите, поскольку он предназначен, чтобы быть универсальным.

Проект

Странице проекта, с примерами и документацию можно посмотреть здесь:

https://fl4m3ph03n1x.github.io/heartbeatjs/index.html

Код

Эта библиотека в основном набор геттеров и сеттеров, смешанной с Некоторые таймеры. Хотелось бы второе мнение по поводу кода и возможных ошибок можно найти, как я объявила о выпуске следующей версии уже на следующей неделе.

const isFunction = require("lodash.isfunction");


const DEFAULT_TIMEOUT = 5000;
const DEFAULT_INTERVAL = 3000;

const heartBeatFactory = () => {

    let interval = DEFAULT_INTERVAL,
        timeout = DEFAULT_TIMEOUT,
        ping,
        pong,
        timer,
        lastHeartbeatTime,
        timeoutTimer,
        hasStarted = false;

    const events = {
        timeout: () => {}
    };

    const hasTimedOut = () =>
        Date.now() - lastHeartbeatTime > timeout;

    const getBeatInterval = () => interval;

    const setBeatInterval = newInterval => {
        if(isNaN(newInterval))
            throw new TypeError(`${newInterval} must be a Number.`);

        interval = newInterval;
    };

    const getBeatTimeout = () => timeout;

    const setBeatTimeout = newTimeout => {
        if(isNaN(newTimeout))
            throw new TypeError(`${newTimeout} must be a Number.`);

        timeout = newTimeout;
        clearTimeout(timeoutTimer);
        timeoutTimer = setTimeout(events.timeout, getBeatTimeout());
    };

    const getPing = () => ping;

    const setPing = newPing => {
        ping = newPing;
    };

    const getPong = () => pong;

    const setPong = newPong => {
        pong = newPong;
    };

    const receivedPong = () => {
        lastHeartbeatTime = Date.now();
        clearTimeout(timeoutTimer);
        timeoutTimer = setTimeout(events.timeout, getBeatTimeout());
    };

    const stop = () => {
        lastHeartbeatTime = undefined;
        clearInterval(timer);
        timer = undefined;
        clearTimeout(timeoutTimer);
        timeoutTimer = undefined;
    };

    const start = fn => {
        if (!isFunction(fn))
            throw new TypeError(`${fn} must be a function.`);

        hasStarted = true;
        lastHeartbeatTime = Date.now();
        timer = setInterval(fn, getBeatInterval());
        timeoutTimer = setTimeout(events.timeout, getBeatTimeout());
    };

    const onTimeout = fn => {
        if (!isFunction(fn))
            throw new TypeError(`${fn} must be a function.`);

        events.timeout = fn;
    };

    const isBeating = () => timer !== undefined;

    const reset = () => {
        if (isBeating())
            stop();

        if( hasStarted ){
            setBeatInterval(DEFAULT_INTERVAL);
            setBeatTimeout(DEFAULT_TIMEOUT);
            ping = undefined;
            pong = undefined;
            onTimeout(() => {});
        }
    };

    return Object.freeze({
        getBeatInterval,
        setBeatInterval,
        getBeatTimeout,
        setBeatTimeout,
        hasTimedOut,
        getPing,
        setPing,
        getPong,
        receivedPong,
        setPong,
        stop,
        start,
        reset,
        isBeating,
        onTimeout
    });
};

module.exports = heartBeatFactory;


132
0
задан 28 марта 2018 в 03:03 Источник Поделиться
Комментарии
2 ответа

Просто интересно, почему вы не hasStarted = false либо в stop() или в reset() метод.

Делая это в stop() вы могли пропустить второй if в reset() метод.

Увидев reset() метод, по крайней мере кричит для того, чтобы сбросить все значения по умолчанию.

2
ответ дан 28 марта 2018 в 04:03 Источник Поделиться

ТЛ;ДР: код-это перебор.

const isFunction = require("lodash.isfunction");

Зачем тебе вообще это нужно. Это ненужная зависимость, когда вы можете просто использовать typeof и проверить, если результат function.

let interval = DEFAULT_INTERVAL,
timeout = DEFAULT_TIMEOUT,
ping,
pong,
timer,
lastHeartbeatTime,
timeoutTimer,
hasStarted = false;

Я обычно рекомендую var/let/const в переменной. Избавит вас от этих надоедливых трейлинг-запятые. И если вы задаетесь вопросом "Ой, а по одному, мне еще нужно использовать ;", точки с запятой являются необязательными, а также. Случаи необходимости использования ; что на самом деле делает что-то очень узкое.

if(isNaN(newInterval))
throw new TypeError(`${newInterval} must be a Number.`);

Типа во время выполнения техники безопасности-это просто ненужные накладные расходы. Я предлагаю вам просто дать код, чтобы взорвать, если потребитель использует неправильный тип. Этого достаточно для них, чтобы знать, что они должны исправить что-то. Если вы хотите настоящей безопасности, использовать типизированный язык, как машинопись, или если вы не можете иметь ТС, используйте комбинацию комментариев JSDoc и Линтер, который использует определения типа намек типов.

return Object.freeze({
getBeatInterval,
setBeatInterval,
getBeatTimeout,
setBeatTimeout,
hasTimedOut,
getPing,
setPing,
getPong,
receivedPong,
setPong,
stop,
start,
reset,
isBeating,
onTimeout
});

Замораживание объекта и ненужных накладных расходов. Есть небольшой выигрыш в замораживании свойства экземпляра. Потребителем библиотека, вероятно, имеет ни малейшего желания ломать свои объекты, если они решили использовать его.

const heartBeatFactory = () => { }

Заводы хороши, когда они возвращают данные, потому что каждый возвращаемое значение представляет собой уникальное значение каждый раз. Но с помощью фабрики для создания объектов с общим поведением как методов не является эффективным. Каждый раз, когда вы звоните на фабрику, вы создаете дубли одной и той же функции каждый раз. Я предлагаю вам использовать конструкторы/вместо классов. Этак, данные для каждого экземпляра, а методы на прототип, общие для всех экземпляров.

Дополнительный бонус для занятия заключается в том, что вы получаете синтаксис геттер/сеттер бесплатно.

class HeartBeat {
constructor (){
this.interval = 3000
this.timeout = 5000
this.ping = null
this.pong = null
this.timer = null
this.lastHeartBeatTime = null,
this.timeoutTimer = null
this.hasStarted = false
}

get hasTimedOut(){
return Date.now() - this.lastHeartBeatTime > timeout
}

get beatInterval(){
return this.interval
}

... and so on.
}

const heartBeatInstance = new HeartBeat()
console.log(heartBeatInstance.hasTimedOut)

А пока это отличное дополнение к языку, я часто нахожу аксессоры перебор, особенно если все они делают это только получить/установить данные. Это, наверное, лучше иметь общественную собственность. И хорошая вещь о JS геттеры/сеттеры заключается в том, что публике, они читаются и назначается как обычные свойства объекта. Если вы переход от общественной собственности к геттеры/сеттеры, все, что вам нужно, это выставить геттер/сеттер с одноименным названием, и переименовать базовых переменных.

0
ответ дан 29 марта 2018 в 01:03 Источник Поделиться