Nie ma pojęcia, co próbujesz osiągnąć, ponieważ w znacznym stopniu zależy od Twoich potrzeb. Poniżej znajduje się coś nieco ogólnego. Bez solidnego zrozumienia tego, co dzieje się w poniższym kodzie, naprawdę może nie chcieć tego użyć.
// Debounce state constructor
function debounce(f) {
this._f = f;
return this.run.bind(this)
}
// Debounce execution function
debounce.prototype.run = function() {
console.log('before check');
if (this._promise)
return this._promise;
console.log('after check');
return this._promise = this._f(arguments).then(function(r) {
console.log('clearing');
delete this._promise; // remove deletion to prevent new execution (or remove after timeout?)
return r;
}.bind(this)).catch(function(r) {
console.log('clearing after rejection');
delete this._promise; // Remove deletion here for as needed as noted above
return Promise.reject(r); // rethrow rejection
})
}
// Some function which returns a promise needing debouncing
function test(str) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('test' + str);
resolve();
}, 1000);
});
}
a = new debounce(test); // Create debounced version of function
console.log("p1: ", p1 = a(1));
console.log("p2: ", p2 = a(2));
console.log("p1 = p2", p1 === p2);
setTimeout(function() {
console.log("p3: ", p3 = a(3));
console.log("p1 = p3 ", p1 === p3, " - p2 = p3 ", p2 === p3);
}, 2100)
Zobacz konsola, gdy uruchomiony powyższy kod. Włożyłem kilka wiadomości, żeby pokazać trochę o tym, co się dzieje. Najpierw pewna funkcja, która zwraca obietnicę, jest przekazywana jako argument do new debounce()
. Spowoduje to utworzenie odfiltrowanej wersji funkcji.
Po uruchomieniu funkcji wyrzuconej w powyższym kodzie (a(1), a(2), and a(3)
) zauważysz, że podczas przetwarzania zwraca tę samą obietnicę, zamiast uruchamiać nową. Gdy obietnica jest kompletna, usuwa starą obietnicę. W powyższym kodzie czekam na timeout ręcznie z setTimeout przed uruchomieniem (3).
Możesz usunąć obietnicę również w inny sposób, np. Dodając funkcję resetowania lub usuwania na debounce.prototype, aby usunąć obietnicę w innym czasie. Możesz także ustawić go na timeout. Testy w dzienniku konsoli powinny pokazywać, że p1 i p2 otrzymują tę samą obietnicę (porównanie porównania "===" jest prawdziwe) i że p3 jest inne.
jak jest 'debounce' funkcja będzie używana? – Aprillion
Co to jest "wewnętrzny"? – thefourtheye
@Apillion Jest on używany jako standardowa funkcja odbicia, podobnie jak funkcja odbicia dostarczona przez [lodash] (https://lodash.com/docs#debounce), z tym że chcę, aby wywołujący mieli dostęp do wartości zwracanej wewnętrznej funkcjonować poprzez obietnicę. Czy to jest odpowiedź na Twoje pytanie? Mogę rozwinąć dalej, jeśli nie. – Chris