JSFiddle - React, Tailwind, and code Playground
by Hellfrom
JavaScript
//скопы создаются с помощью scope конструктора
function Scope(){
this.$$watchers = [];
this.$$asyncQueue = []; //задачи, которые нужно будет выполнить когда-то
this.$$postDigestQueue = []; //задачи, которые выполнятся после $digest, но не запустят $digest()
this.$$phase = null; // фаза $digest цикла
};
//ф-ия принимает ф-ию наблюдения и ф-ию callback
Scope.prototype.$watch = function (watchFn, listenerFn, valueEq){
var watcher = {
watchFn : watchFn,
listenerFn : listenerFn||function (){},
valueEq : !!valueEq //если указан 3-й параметр будет глубокое сравнение
};
this.$$watchers.push(watcher);
};
//цикл обхода всех наблюдателей 1 раз
Scope.prototype.$$digestOnce = function (){
var self = this;
var dirty; //был ли изменёно что-то
_.forEach(this.$$watchers,function (watch){
try{
//запускаем наблюдатель
var newValue = watch.watchFn(self);
var oldValue = watch.last;
//если предыдущее возвращаемое наблюдателем значение не равно новому запустить callback
//if(newValue !== oldValue){ //сравнивает строки
if (!self.$$areEqual(newValue, oldValue, watch.valueEq)) {
watch.listenerFn(newValue, oldValue, self); //self == scope
//если хоть в каком-то наблюдателе изменилось значение return
dirty = true; //возвращаем маркер - изменение
watch.last = newValue;
}
}catch(e){
(console.error||console.log)(e);
}
});
return dirty;
};
Scope.prototype.$digest = function (){
var dirty;
var ttl = 10; //количество допустимых мутаций (Time To Live)
this.$beginPhase("$digest");
do{
//реализуем все отложенные ф-ии
while(this.$$asyncQueue.length){
try{
var asyncTask = this.$$asyncQueue.shift();
this.$eval(asyncTask.expression);
}catch(e){
...