Коли ви пишите JavaScript-код іноді виникає потреба запустити функцію на наступний тік. Для цього використовують setTimeout
, і якщо ви використовуєте Angular, то вам повинен бути знайомий такий хак.
setTimeout(() => {
// Код, розміщений тут буде запущено на наступний тік
}, 0);
Можливо, я божевільний, але писати такий код огидно! Я хочу зробити його чистішим та приємнішим. Це ми і спробуємо зробити, написавши декоратор.
Давайте створимо метод-декоратор timeout
(TypeScript):
function timeout( milliseconds: number = 0 ) {
return function( target, key, descriptor ) {
var originalMethod = descriptor.value;
descriptor.value = function (...args) {
setTimeout(() => {
originalMethod.apply(this, args);
}, milliseconds);
};
return descriptor;
}
}
В TypeScript чи Babel декоратор — це звичайний метод, що приймає три параметра:
-
target
– функція конструктора класу для статичного об'єкту або прототип класу для конкретного екземпляру. -
key
– назва об'єкта. -
descriptor
– дескриптор властивості для цього обєкта.
Так як наш декоратор повинен приймати аргумент, нам слід використовувати Decorator Factory. Це простий патерн, суть якого полягає в тому, що виклик timeout(42)
поверне справжній декоратор, який і буде застосовано до функції.
Ми можемо звертатися до оригінального методу за допомогою дескриптора, після чого створюємо новий метод, що обгортає оригінальний код в setTimeout
.
Можна писати так:
class DemoComponent {
constructor() {}
@timeout()
demoMethod() {
// Цей код запуститься на наступний тік
}
@timeout(2000)
demoMethod2() {
// А цей через дві секунди
}
}
new DemoComponent().demoMethod();
Виглядає круто, чи не так? І хоча поки що декоратори доступні лише в TypeScript або з використанням Babel, це не робить їх менш потужними, а використання менш приємним. Ви можете дізнатися більше про декоратори в JS тут.
Також у нас є стаття про декоратори в Python, з цікавими прикладами ;)
Ще немає коментарів