Хм, вы носите здесь множество взаимно ссылочных универсальных типов, и без использования и примеров использования, я признаю, я почти не представляю, что здесь происходит, и действительно ли это лучший способ представить вашу структуру данных , Я предполагаю, что вы, вероятно, могли бы обойтись без единственного параметра типа, подобного этому:
class Obj
{
constructor(public fields: { [K in keyof T]: Obj }) {
}
public data!: T
}
Но даже если вы сделаете это, у вас все равно будет та же проблема, которая обнаружится, если вы включите более строгий режим [119 ] опции компилятора , такие как --noImplicitAny
или --strict
. Затем вы увидите, что ваше определение recursive
дает вам следующие ошибки:
blockquote>
'recursive' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
и
[ 117]
blockquote>Это предполагаемое поведение , когда компилятор не может вывести тип, потому что он определенным образом зависит от самого себя. Предлагаемый способ справиться с этим обычно состоит в том, чтобы дать явную аннотацию типа одной из частей, чтобы разорвать круглость. Это раздражает, потому что вынуждает вас избыточно записывать наборы к вещам, которые были ранее выведены компилятором, но я не знаю, есть ли хороший способ избежать этого.
Вот один из способов сделать это с типами, какими они у вас являются:
// explicit type interface RecursiveObj extends Obj< DataType< { readonly query: RecursiveObj; test: Obj<{}, {}>; } >, { readonly query: RecursiveObj; test: Obj<{}, {}>; }> { } const recursive = new Obj({ // explicitly annotated return type get query(): RecursiveObj { return recursive }, test: new Obj({}) }); // okay now
И вот как я это сделаю с упрощенным
[112 ]Obj
типом I, перечисленным выше:Хорошо, надеюсь, это поможет. Удачи!
Я подозреваю, что это может быть трудно или даже невозможно в JavaScript
Ваше подозрение корректно. Методы как анимации, циклы ввода данных пользователем и ‘async=true’ XMLHttpRequests должны возвратить управление браузеру для продолжения, и браузер не может возвратить управление, пока каждый уровень вложенности вызова функции не возвратился. Это означает весь Ваш код, включая функцию, которая звонила ‘holdTillFinished ()’, должен будет раскрутиться: поэтому ‘holdTillFinished ()’ невозможен.
Другие языки имеют функции управления потоком, которые позволяют Вам эффективно выполнять асинхронный процесс как тот, который, кажется вызывающей стороне синхронен, и так же наоборот. Самыми известными являются потоки и продолжения. JavaScript не обладает этими средствами, таким образом, лучшими, которые можно сделать, являются тайм-ауты и обратные вызовы.
(Определение обратного вызова как подставляемая функция для получения доступа к переменным функции включения в закрытии действительно, по крайней мере, вынимает часть боли из него; некоторые другие языки должны начать переносить каждый бит включения состояния в свойствах объекта для достижения этого.)
Вы могли использовать публиковать/подписывать архитектуру для достижения того, что Вы хотите. Не зная очень о том, чего точно Вы хотите достигнуть, мое предположение, это будет работать на Вас.
Путем это работает, то, что Вы смотрите на завершение функции как событие, которое можно слушать и присоединить обработчики к. Dojo имеет pubsub механизм, хотя я уверен, что существуют другие.
Вы, вероятно, ищете http://docs.jquery.com/Effects/queue
Но если Вы ищете более обобщенный способ задержать вещи, я использовал этот отрывок прежде (я не записал это, таким образом, весь кредит переходит к исходному автору):
//Simple wrapper enabling setTimout within chained functions.
$.fn.wait = function(time, type) {
time = time || 1000;
type = type || "fx";
return this.queue(type, function() {
var self = this;
setTimeout(function() {
$(self).dequeue();
}, time);
});
};