Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Упрощенный Deferred (https://javascript.ru/forum/project/22357-uproshhennyjj-deferred.html)

float 29.10.2011 14:34

Цитата:

resolve-ит все объявленные стадии и глобальный обработчик?
нет не ресолвит. просто принудительно вызывает глобальные обработчики. это сразу планировался как внутренний метод. он вызывается когда все стадии выполнены.
и тут есть запарка, когда его вызывают из вне.
при таком вызове точно не ясно что делать с обработчиками success и err...
сейчас если диферд без стадий вызывается success(тк reject-а не было) и anyway

Gvozd 29.10.2011 14:56

Цитата:

Сообщение от float
это сразу планировался как внутренний метод.

мне кажется и не стоит его выносить.
Ведь, тогда вы обманываете обработчики, говоря им, что событие уже выполнилось, но результатов события получить при этом нельзя

float 29.10.2011 15:18

Цитата:

тогда вы обманываете обработчики
да. с этой позиции вы правы.
но есть другой момент.
у диферда вообще может не быть стадий. а success err anyway можно вешать.
логично иметь метод чтобы их вызвать...

float 29.10.2011 17:33

только я думаю надо чуть изменить.
finish зарыть.
а success err anyway можно сделать разное поведение в зависимости от аргументов.
функция - добавление в очередь. иначе вызов обработчиков в контексте с параметрами.

x-yuri 30.10.2011 03:52

float, а ты своим кодом просто продемонстрировал использование или подобный код действительно для чего-то используется? Если первое, можешь привести какой-нибудь рельный пример, когда нужен Deferred? Если второе, объяснить...

float 30.10.2011 16:42

Просто перед тем как написать диферд, я прикинул что и как должно быть.
Когда видишь что должно получиться легче ориентироваться...

Цитата:

можешь привести какой-нибудь рельный пример
мне такой диферд пригодился для следующего:
в проекте админ панель на попапах(типо как в друпале).
содержимое попапов подгружается не сразу а при клике.
это всё обслуживает 1-н диферд.
там массив стадий с цепочой ajax>animation.
+по статусу стадии удобно смотреть где уже загружен контент а где нет.

а вообще есть 2-я причина такого диферда:
у меня в велосипеде риал-тайм анимация(без очередей как в jquery)
поэтому необходим инструмент согласовки...

x-yuri 31.10.2011 04:12

Цитата:

Сообщение от float
там массив стадий с цепочой ajax>animation.

не знаю, насколько я понял задачу, но почему не сделать как-то так?
new AsyncChain({
    onFailure: function() {
        ...
    }
})
    .add(function(NEXT) {
        new Request({url: ...,
            onSuccess: function() {
                NEXT();
            },
            onFailure: function() {
                this.fireEvent('failure')
            }.bind(this)
        }).post();
    })
    .add(function(NEXT) {
        $(...).get('tween').setOptions({
            onComplete: function() {
                NEXT();
            }
        }).start('left', 100);
    })
    ...
    .run();

float 31.10.2011 05:03

не могу понять из вашего кода что конкретно вы предлагаете поменять...
Цитата:

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

with-love-from-siberia 31.10.2011 06:43

Тема интересная. Что-то подобное уже обсуждалось в другой ветке на форуме. К сожалению все это по большей части "завязано" на браузерную среду либо "тянет" за собой целый ворох полезных, но не всегда нужных методов. Например, в среде WSH нет методов window.setTimeout/setInterval (да и объекта такого нет, хотя его просто получить, например new ActiveXObject('htmlfile').parentWindow). Тем не менее в WSH встречаются задачи, которые требуют синхронизации данных между основным потоком исполнения и потоком, выполняющимся асинхронно. Конкретный пример - временные потребители, следящие за изменением состояния служб Windows:
var wmi = GetObject('winmgmts:\\\\.\\Root\\CIMV2');
var query = 'SELECT * FROM __InstanceModificationEvent WITHIN 5 WHERE TargetInstance ISA "Win32_Service"';
var sink = WScript.CreateObject('WbemScripting.SWbemSink', 'Sink_');
wmi.ExecNotificationQueryAsync(sink, query);

function Sink_OnObjectReady(e)
{
	if ( e.TargetInstance.State != e.PreviousInstance.State ) {
		WScript.Echo('****');
		WScript.Echo(new Date());
		WScript.Echo(e.TargetInstance.DisplayName);
		WScript.Echo('Current state: ' + e.TargetInstance.State);
		WScript.Echo('Previous state: ' + e.PreviousInstance.State);
	}
};

WScript.Echo('**** Waiting for asynchronous event...');

while ( 1 ) {
    WScript.Sleep(1000);
}


Предлагаемые Deferred и Promise решения выглядят красивыми, но громоздкими. Гораздо проще были бы решения вроде предложенной x-yuri.

x-yuri 31.10.2011 07:35

Цитата:

Сообщение от float
не могу понять из вашего кода что конкретно вы предлагаете поменять...

deferred слишком сложный (слишком много возможностей), я не знаю, где его можно на полную использовать. Я предлагаю максимально упростить функциональность.

Цитата:

Сообщение от float
может и можно.
мой код выглядит примерно также, только без лишних телодвижений.

о каких лишних телодвижениях речь? Давай попробую переписать под твой фреймворк:
new AsyncChain({
    onFailure: function() {
        ...
    }
})
    .add(function(NEXT) {
        _.post('some/url.php').success(function(data) {
            NEXT();
        }).err( this.fireEvent('failure') );
    })
    .add(function(NEXT) {
        _('.menu').hide(200, function() {
            if (this.length) {
                NEXT();
            } else { this.fireEvent('failure'); }
        }.bind(this));
    })
    ...
    .run();


Часовой пояс GMT +3, время: 07:03.