Статьи

Реактивная GWT

Вступление

За последние 4 или 5 лет популярность реактивного программирования значительно выросла. Это может сказать нам, что сценарий использования реактивных приложений теперь действителен как никогда. Нагрузка на бэкэнд-системы возросла и, соответственно, необходимость справляться с этим с минимальными ресурсами. Реактивное программирование рассматривается как способ повышения эффективности и производительности при одновременном снижении потребления ресурсов. Популярность реактивного программирования привела к разработке реактивных расширений для большинства языков программирования и платформ: GWT не является исключением. В этом посте мы приведем пример использования rxjava-gwt, который является реактивным расширением для GWT.

О пользователе rxjava-gwt

rxjava-gwt — это адаптация RxJava к GWT, а не оболочка для RxJ, как некоторые могут поверить. По словам создателя проекта Игнасио Бака , адаптация RxJava к GWT более полезна, чем упаковка RxJ, особенно если код Rx является общим для клиента и сервера, потому что здесь поведение точно такое же. Кроме того, это предоставляет возможность совместного использования пользовательских операторов или композиций Rx.

Случаи применения

С точки зрения бэкэнда реактивное программирование рассматривается как способ повышения эффективности и производительности, а также для выполнения запросов с минимальным потреблением ресурсов, но как насчет внешнего интерфейса? Что ж, мы знаем, что JavaScript по своей сути асинхронный, и использование обратных вызовов / обещаний является обычным делом, так что же нужно добавить реактивности? Во-первых, это может помочь сделать приложение более отзывчивым, если приложение вызывает внешние источники данных (например, HTTP-запросы, веб-сокеты, события, отправленные сервером), преобразовывая эти источники в поток и реагируя на поступающие данные, а не ожидая целостности данных. быть доступным. Во-вторых, реактивное программирование может помочь объединить несколько источников событий в один основной поток, если выполняемые действия являются общими.

пример

Предположим, мы хотим создать простой интерфейс для знаменитой библиотеки curl . Мы хотим иметь три поля (url, method и body data), и мы хотим, чтобы наша команда curl генерировалась при вводе. Это похоже на хороший пример использования реактивного программирования, поскольку у нас есть несколько источников событий, которые требуют одинаковой обработки. Используя традиционный режим программирования, мы должны выполнить одно и то же действие для каждого обработчика событий.

HTML

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
<div class="form-container">
    <label for="url">URL:</label>
    <input id="url" type="text"></input>
    <label for="method">Method: </label>
    <select id="method">
      <option selected value="GET">GET</option>
      <option value="POST">POST</option>
      <option value="PUT">PUT</option>
      <option value="DELETE">DELETE</option>
      <option value="PATCH">PATCH</option>
      <option value="HEAD">HEAD</option>
      <option value="OPTIONS">OPTIONS</option>
      <option value="CONNECT">CONNECT</option>
      <option value="TRACE">TRACE</option>
    </select>
    <label for="data">Data: </label>
    <textarea id="data"></textarea>
    <div id="result">curl <span id="generatedCommand"></span></div>
  </div>

Код

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
HTMLInputElement urlInput = (HTMLInputElement) DomGlobal.document.getElementById("url");
  HTMLSelectElement methodInput = (HTMLSelectElement) DomGlobal.document.getElementById("method");
  HTMLTextAreaElement dataInput = (HTMLTextAreaElement) DomGlobal.document.getElementById("data");
  HTMLElement generatedCommand = (HTMLElement) DomGlobal.document.getElementById("generatedCommand");
  final String[] commands = new String[3];
 
    Observable urlStream = Observable.create((emitter) -> {
      urlInput.onkeyup = (event) -> {
        HTMLInputElement urlInputTarget = (HTMLInputElement) event.target;
        emitter.onNext(new Command(2, urlInputTarget.value));
        return null;
      };
    });
 
    Observable methodStream = Observable.create((emitter) -> {
      methodInput.onchange = (event) -> {
        HTMLSelectElement methodSelect = (HTMLSelectElement) event.target;
        emitter.onNext(new Command(1, "-X"+methodSelect.value));
        return null;
      };
    });
 
 
    Observable dataStream = Observable.create((emitter) -> {
      dataInput.onkeyup = (event) -> {
        HTMLTextAreaElement dataInputTarget = (HTMLTextAreaElement) event.target;
        emitter.onNext(new Command(3, "-d '"+dataInputTarget.value+"'"));
        return null;
      };
    });
 
    Observable.merge(urlStream, methodStream, dataStream).subscribe((obs) -> {
      commands[obs.position - 1] = obs.value;
      generatedCommand.textContent = String.join(" ", Stream.of(commands)
                                                            .filter(Objects::nonNull)
                                                            .collect(Collectors.toList()));
    });
 
  }
}

Вывод

rxjava-gwt открывает двери в реактивный мир для разработчиков GWT. Мы видели несколько вариантов использования, которые имеют смысл для реактивного программирования, поэтому разработчикам GWT пора попробовать реактивную модель в своих приложениях, когда она будет иметь смысл.

Другие примеры

Опубликовано на Java Code Geeks с разрешения Закарии Амине, партнера по нашей программе JCG . Смотреть оригинальную статью здесь: реактивная GWT

Мнения, высказанные участниками Java Code Geeks, являются их собственными.