Как переписать / отменить предыдущее обещание, названное одно за другим? - PullRequest
0 голосов
/ 06 апреля 2019

У меня есть код jQuery, который отвечает на нажатие клавиатуры пользователя, и я проверяю, отображается ли элемент. Плагин возвращает обещание, если пользователь нажимает клавишу очень быстро или удерживает ее (сейчас это слишком быстро для моего кода), это создает обещание в виде цикла. Я хочу отменить предыдущее обещание, прежде чем позвонить новому.

Я придумал этот код, который игнорирует предыдущее обещание:

var scroll_callback_counter = 0;
function move_cursor_visible() {
    var cursor = self.find('.cursor');
    var i = scroll_callback_counter++;
    return cursor.is_fully_in_viewport(self).then(function(visible) {
        if (i === scroll_callback_counter && !visible) {
            var offset = cursor.offset();
            var container_offset = self.offset();
            self.scrollTop(offset.top - container_offset.top - 5);
            return true;
        }
    });
}

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

EDIT:

Вот is_fully_in_viewport функция:

function jquery_resolve(value) {
    var defer = jQuery.Deferred();
    defer.resolve(value);
    return defer.promise();
}
$.fn.is_fully_in_viewport = (function() {
    function is_visible(node, container) {
        var box = node.getBoundingClientRect();
        var viewport = container[0].getBoundingClientRect();
        var top = box.top - viewport.top;
        var bottom = box.bottom - viewport.top;
        var height = container.height();
        return bottom > 0 && top <= height;
    }
    if (window.IntersectionObserver) {
        return function(container) {
            var node = this[0];
            var defer = jQuery.Deferred();
            var item_observer = new window.IntersectionObserver(function(entries) {
                defer.resolve(entries[0].isIntersecting);
                item_observer.unobserve(node);
            }, {
                root: container[0]
            });
            item_observer.observe(node);
            return defer.promise();
        };
    } else {
        return function(container) {
            return jquery_resolve(is_visible(this[0], container));
        };
    }
})();

1 Ответ

0 голосов
/ 06 апреля 2019

Создает отклоненную функцию, которая задерживает вызов func до ждать миллисекунды, прошедшие с момента последнего функция была вызвана.

Вы можете использовать debounce метод loadash,

_.debounce(func, [wait=0], [options={}])

Функция debounce поставляется с методом отмены для отмены отложенного вызовы func и метод flush для немедленного их вызова

...