-
-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
destructor может вызываться много раз? #274
Comments
Еще вопрос, в коде атомов везде используется $mol_atom.stack[0], а зачем тогда массив? |
Никто. Раньше владелец проходился по всему имуществу и дестроил его, но со внедрением атомов это лишь лишние тормоза.
Да, вместе с контекстами хочу что-то такое замутить.
Так и задумано, чтобы при дестрое не искать атом в запланированных на обновление - он просто ничего не сделает. Уничтоженный атом не предназначен для дальнейшего использования.
Потому, что это алиас для записи в $mol_state_stack. Я планировал его использовать для чего-то типа зон. Без которых атомы не совместимы с node-fibers. |
А если надо что-то вроде такого замутить? class AutocompleteService {
@force $: AutocompleteService
@mem nameToSearch: string = ''
@props set props({initialValue}: IAutocompleteProps) {
this.nameToSearch = initialValue
}
_handler: number = 0
destructor() {
clearTimeout(this._handler)
}
@mem get searchResults(): string[] {
clearTimeout(this._handler)
const name = this.nameToSearch
this._handler = setTimeout(() => {
fetch(`/api/autocomplete?q=${name}`)
.then((r: Response) => r.json())
.then((data: string[]) => {
this.$.searchResults = data
})
.catch((e: Error) => {
this.$.searchResults = e
})
}, 500)
throw new mem.Wait()
}
@mem
set searchResults(searchResults: string[] | Error) {}
setValue = (e: Event) => {
this.$.nameToSearch = (e.target: any).value
}
} Кто в хосте вызовет destructor, чтоб таймер подчистить? Или правильнее handler переделать на атом, который возвращает объект с свойством destroy? тогда прозрачность теряется.
DI, по-мне лучше, т.к. все создает объекты он, там любые преобразования над ними легко сделать. Еще контракт появляется у класса, не надо вчитываться в методы и смотреть, что они там из контекста используют. Еще класс становится пригоден для работы где угодно, вне контекстов mol.
Это почему же? Вот такой кейс разве не должен отрабатываться? let destroyed: string = ''
class A {
@mem
foo(): number {
destroyed = ''
return 1
}
destructor() {
destroyed = 'foo'
}
}
class B {
_a = new A()
@mem
showing(next?: boolean): boolean {
return next === undefined
? true
: next
}
@mem
bar(): ?number {
return this.showing()
? this._a.foo()
: null
}
}
const b = new B()
assert(b.bar() === 1)
assert(destroyed === '')
b.showing(false)
b.bar()
sync()
assert(destroyed === 'foo')
b.showing(true)
sync()
assert(destroyed === '') Заюзали атом, потом перестали, потом опять заюзали.
Может просто вынести static-и из атомов в отдельную сущность и назвать ее контекстом, чем так мудрить? |
Если экземпляр AutocompleteService создаётся через атом, то он и вызовет деструктор. Если это синглтон, то да в отдельном свойстве создаём объект с конструктором (взводит таймер) и деструктором (сбрасывает таймер). Что-то типа:
Соответственно этот вложенный класс лучше реализовать отдельным ReactiveTimerService-ом.
Так одно другое не исключает. И контекст инъектится точно так же как любые другие свойства.
А зачем вам знать что они там используют? :-)
В этот момент атом выкидывается из памяти. Иначе бы число атомов росло неограниченно. Когда появится зависимость - атом будет создан снова.
$mol_state_stack и есть такая сущность - состояние привязанное к стеку. Соответственно это состояние можно сохранить перед сменой стека (например, через node-fibers), а потом восстановить при возвращении стека. |
Что б не завязываться на магический this.$, который vendor lock-in
А если, как в примере |
Ну так если _a - нереактивный мембер, то и дестроить его просто так нельзя. Я бы сделал его реактивным и тогда при потере зависимостей будет уничтожаться и А и владеющий им атом:
Но вот если атомы используются напрямую, а не через $mol_mem (который собственно атом и выкидывает), то да, согласен, надо позволить ему восстанавливаться после уничтожения. |
У меня логика была такая: если в классе все атомы дестроятся, то вызывать деструктор у класса. |
Класс и без активных атомов может быть валидным. |
Да понятно, что так себе решение. Просто делать инстанс атомом ради деструкции, тоже кажется странным. Это ж не бесплатно все. |
Не сам инстанс, а фабрику его создающую. Вполне нормально на мой взгляд. |
В tree может и нормально, но в классе забыть сделать атомом легко. Т.к. смысл атома в реактивности, а она в этом месте не нужна, не очевидно получается. |
Смысл mem в создании по требованию и кешировании. Когда привыкаешь к ленивости - не забываешь. |
Ну это субъективно. Это в вашей mol-песочнице может и привычно. По-требованию это хорошо, но получается все тотально надо заворачивать в фабрики, так себе решение. Вместо class B {
_a = new A()
} писать class B {
@mem _a() { return new A() }
} Спрашивается, а зачем, если класс B и так живет только вместе с компонентом, в котором используется. |
В том-то и дело, что время жизни владельца может быть существенно больше времени жизни имущества. Например, при ленивом рендеринге сразу создаются вьюшки для каждого элемента списка - это ровно по объекту на элемент, что относительно быстро и экономит память. Но вложенные в них объекты создаются лишь когда эти элементы реально рендерятся. |
Да я понимаю, просто это как-то проникает на все слои. Логичнее свой язык изобрести, вроде purescript, чем из говна и палок, с кучей условностей, стоить новую парадигму на языке, который под это не предназначен. |
Логичнее, но нужно написать кучу утилит и плагинов к IDE и всё равно пересадить людей на свой язык будет непосильной задачей. view.tree тому пример :-D |
Вопрос возник, почему столько генераций функций в mol, даже там, где ленивость не нужна, как хэндлеры для атомов и деструкторы в mem: const destructor = atom.destructor
atom.destructor = ()=> {
store.delete( host )
destructor.call( atom )
} Памяти они больше жрут, время на генерацию чуть больше. Если все приложение в таком стиле написано, то разница может быть существенная. Я смоделировал на бешенном кол-ве итераций, но все же. Почему просто классы не создавать или больше деталей прокидывать в атом? да, будет чуть больше кода, но памяти то меньше. |
Ну, на микробенчмарке разница в 2 раза. А в реальном приложении - капля в море. |
Атомов может быть 10к, если dict учитывать, там разница будет 10-15% |
Может, но к ним и объектов будет не одна тысяча, а к ним биндингов ещё в несколько раз больше, а биндинги через классы делать - совсем много кода. |
С биндингами тут тоже есть всякие ухищрения, когда контекст передается отдельно, вроде как в inferno onClick={[this, func]}. Я к тому, что генерацию функций пытаются всячески избежать. Сейчас наверное это не так актуально, правда. А вот во времена bluebird, запарывались этим, поэтому он быстрее нативных и всяких q был, где генерация на генерации. |
Я тоже раньше избегал, и раньше создание замыканий действительно долгим было. К сожалению, вариант с отдельной передачей контекста плохо дружит со статической типизацией. |
Я думаю, this в функциях допилят скоро Typescript: class A {
x: number
}
function f(this: A, a: number) {
this.x = 3;
}
class B {}
const b = new B()
f.call(b, 1) flow: class A {
x: number
}
function f(a: number) {
(this: A);
this.x = 3;
}
class B {}
const b = new B()
f.call(b, 1)
В ts, в отличие от flow, call пока не typesafe, flow вообще зашибись типы выводит. |
Тут дело даже не в проверке, а в том, что когда пишешь код внутри функции среда разработки не знает тип this и приходится его писать вручную, что для однострочников сильно избыточно. |
https://github.com/eigenmethod/mol/blob/master/atom/atom.ts#L39
Не пойму, как работают деструкторы. Если destructor есть у хоста, но хост не свойство атома, кто тогда его вызовет.
Не планируется вообще убрать функциональность с овнерами из mol_object в мапу, или хотя бы примешивать? Тогда можно для обычных объектов, не унаследованных от mol_object тоже использовать эти фичи.
Смущает то, что протекает этот mol_object на все слои.
Это не бага?
Если после destroy произойдет get, мы получим undefined, если force не использовать.
The text was updated successfully, but these errors were encountered: