Реальное реактивное программирование в JavaScript

Без фреймворка можно запрограммировать по формулам, как с помощью электронной таблицы, благодаря динамизму JavaScript.

Реактивное программирование - третий уровень в высокоуровневом программировании: Первый уровень был достигнут с появлением таких языков, как Fortran и Basic, а затем в 1967 году Симула вывел нас на второй уровень с объектами, реализованными сейчас во всех языках. Возможно, пришло время перейти на новый уровень.

Потому что PR ближе к тому, как думать о человеке, чем императивное программирование (тип рецепта приготовления пищи), и я не говорю о функциональном программировании !
Пример. Если бы я хотел оценить расстояние, которое можно преодолеть с помощью разных моделей автомобилей, я бы написал:

расстояние = емкость бака/расход * 100

Тогда все, что мне нужно сделать, - это ввести вместимость бака и расход различных моделей автомобилей, и у меня всегда была бы их автономность. Никаких дополнительных строк кода не требуется, как и в электронной таблице, первое приложение PR.

PR особенно подходит для программирования робота, симуляции или придания игры интеллекта. Результаты, как и указанное выше расстояние, могут отображаться через интерфейс или быть командами для реального устройства или виртуального объекта.

Есть несколько фреймворков, которые утверждают, что добавляют реактивное программирование в JavaScript, но по тестам, которые я провел, не очевидно, что они могут пересчитать формулу, назначенную переменной. Они просто распространяют события, так что это скорее так называемое программирование событий. Приведенный ниже сценарий позволяет программе работать как электронная таблица, все формулы пересчитываются при изменении параметра. Вот почему я добавил «правда» наряду с «реактивным программированием» в заголовке.

Разработав тот же скрипт на PHP после JavaScript-версии, я оценил, как удалось так просто реализовать эту парадигму в JS, благодаря динамизму языка.
В JavaScript я реализую его с объектом, который держится в 20 строках кода...

var Reactol = (function() {
Reactol.prototype.add = function(x) {
this.depend.push(x)
}
Reactol.prototype.change = function(x) {
if(x != undefined) this.value = x for(var i in this.depend) {
var d = this.depend[i]
d.action()
d.change() d.output()
}
}
function Reactol() {
this.depend=[]
this.value=0
}
return Reactol;
})();

Как мы видим, я использую закрытие, чтобы добавить конструктор к объекту Reactol.

Зависимая таблица содержит список объектов, зависящих от текущего объекта. Метод add позволяет добавить зависимость.

При желании изменить значение объекта называется метод, который в свою очередь вызывает методы действия, изменения и вывода каждого объекта, зависящего от него.

Объявление активной переменной

Реактивная переменная представлена объектом Reactol, поэтому сначала объявляется экземпляр объекта:

var v1 = new Reactol()

Затем определяется формула, которая должна быть назначена этой переменной:

v1['action'] = function() { this.value = 10  }

При необходимости будет добавлен метод отображения содержимого переменной. Это также может быть команда для механизма.

v1['output'] = function() { document.getElementById("sum").value = this.value }

Теперь мы создаем зависимость, определяем другую переменную v2, которая зависит от переменной v1.

var v2 = new Reactol()
v2['action'] = function() { this.value = v1.value + 1000 }
v1.add(v2) 

Для добавления v2 в список зависимых от него переменных необходимо вызвать метод add v1. В дальнейшем каждое изменение v1 приведет к автоматическому обновлению v2.

Больше ничего не нужно, чтобы сделать наши переменные реактивными!

Пример на HTML-странице

У нас есть две переменные v1 и v2, которые связаны с текстовыми полями на HTML-странице.

Мы хотим определить новую переменную sum, значение которой равно сумме v1 и v2, которая также будет отображаться в текстовом поле. Таким образом, каждый раз, когда пользователь изменяет значение v1 или v2, sum будет обновляться автоматически.

Вот код JavaScript и HTML:

var Reactol = (function() {
Reactol.prototype.add = function(x) {
this.depend.push(x)
}
Reactol.prototype.change = function(x) { if(x != undefined) this.value = x
for(var i in this.depend) {
var d = this.depend[i]
d.action()
d.change()
d.output()
}
}
function Reactol() {
this.depend=[]
this.value=0
}
return Reactol
})();
var v1 = new Reactol()
var v2 = new Reactol()

var sum = new Reactol()
sum["action"] = function() { this.value = parseInt(v1.value) + parseInt(v2.value) }
sum["output"] = function() { document.getElementById("sum").value = this.value } v1.add(sum)
v2.add(sum)
<p>Value 1 : <input type="text" name="v1" onKeyUp="v1.change(this.value)"> </p>
<p>Value 2 : <input type="text" name="v2" onKeyUp="v2.change(this.value)"> </p>
<p>Sum : <input type="text" name="sum" id="sum"> </p>

Этот упрощенный пример используется только для отображения работы объекта Reactol. Такой же эффект можно было бы получить и без этого предмета, конечно, но если бы было пятьдесят виджетов, зависящих друг от друга, с этим было бы сложнее справиться и в этом случае реактивное программирование берет на себя весь интерес.

Показ

Значение 1:

Значение 2:

Сумма:

Загрузить полный пример. Сценарий лицензируется MIT. Используйте его свободно, но не представляйте на веб-странице, не приписывая автору.

Реактивное программирование реализовано в компиляторе Script JavaScript (выполнен мной самим), используя описанный здесь объект. Достаточно изложить формулы, компилятор отвечает за автоматическое объявление зависимостей.

Денис Суро, 18 сентября 2014 года.