JavaScript Dotazování

Dotazování pomocí JavaScriptu je jednou z těch ošklivých, ale důležitých funkcí v rámci pokročilého uživatelského prostředí a testovacích postupů. Někdy neexistuje událost, do které byste se mohli zapojit, aby znamenala, že daný úkol je splněn, takže si musíte ušpinit ruce a jednoduše si to zažádat. Dotazování pomocí JavaScriptu není obtížné, ale také není snadné. Dovolte mi ukázat vám několik implementací dotazování JavaScriptu, které můžete přidat do svého panelu nástrojů!

Se sliby

Vzhledem k tomu, že rozhraní Promise API je dnes implementováno téměř ve všech prohlížečích, zde je implementace dotazování, která je používá:

// The polling function
function poll(fn, timeout, interval) {
    var endTime = Number(new Date()) + (timeout || 2000);
    interval = interval || 100;

    var checkCondition = function(resolve, reject) {
        // If the condition is met, we're done! 
        var result = fn();
        if(result) {
            resolve(result);
        }
        // If the condition isn't met but the timeout hasn't elapsed, go again
        else if (Number(new Date()) < endTime) {
            setTimeout(checkCondition, interval, resolve, reject);
        }
        // Didn't match and too much time, reject!
        else {
            reject(new Error('timed out for ' + fn + ': ' + arguments));
        }
    };

    return new Promise(checkCondition);
}

// Usage:  ensure element is visible
poll(function() {
	return document.getElementById('lightbox').offsetWidth > 0;
}, 2000, 150).then(function() {
    // Polling done, now do something else!
}).catch(function() {
    // Polling timed out, handle the error!
});

Kód je strukturován dostatečně snadno čitelně, ale většinou se skládá ze tří částí: podmíněná funkce, která signalizuje úspěch dotazování, podmíněné selhání, kterému nevypršel časový limit, takže jej spustíme znovu, nebo selhání, které již uplynulo, což by mělo vrátit chybu.

Bez odložení

Pokud nepoužíváte Odložené, žádný strach – dotazování je téměř stejné:

function poll(fn, callback, errback, timeout, interval) {
    var endTime = Number(new Date()) + (timeout || 2000);
    interval = interval || 100;

    (function p() {
            // If the condition is met, we're done! 
            if(fn()) {
                callback();
            }
            // If the condition isn't met but the timeout hasn't elapsed, go again
            else if (Number(new Date()) < endTime) {
                setTimeout(p, interval);
            }
            // Didn't match and too much time, reject!
            else {
                errback(new Error('timed out for ' + fn + ': ' + arguments));
            }
    })();
}

// Usage:  ensure element is visible
poll(
    function() {
        return document.getElementById('lightbox').offsetWidth > 0;
    },
    function() {
        // Done, success callback
    },
    function() {
        // Error, failure callback
    }
);

Rozdíl je v tom, že neexistuje žádná návratová hodnota – funkce zpětného volání nahrazují instanci Deferred.

Dotazování není nutně důsledkem asynchronního kódování, ale používání a důležitost se rozhodně zvýšilo díky naší touze psát asynchronní kód. Během mého psaní front-endových funkčních testů s Intern testovacím rámcem jsem poměrně dost využíval dotazování jak na straně serveru, tak na straně klienta. Tato technika bude mít vždy své místo, takže se ujistěte, že máte k dispozici takový úryvek.