JavaScript - синхронизация после асинхронных вызовов

Как уже упоминалось в , этот ответ - вы должны добавить 24 часа, если разница отрицательная

def time_difference(time_a, time_b)
  difference = time_b - time_a

  if difference > 0
    difference
  else
    24 * 3600 + difference 
  end
end

20
задан oldNoakes 13 May 2009 в 03:23
поделиться

2 ответа

There is barely another way than to have this counter. Another option would be to use an object {} and add a key for every request and remove it if finished. This way you would know immediately which has returned. But the solution stays the same.

You can change the code a little bit. If it is like in your example that you only need to call another function inside of commonCallback (I called it otherFunction) than you don't need the commonCallback. In order to save the context you did use closures already. Instead of

foo.bar.sendRequest(new RequestObject, function(resp) {
            me.commonCallback(resp);
            });

you could do it this way

foo.bar.sendRequest(new RequestObject, function(resp) {
            --me.expectedCallbacks || me.otherFunction(resp);
            });
5
ответ дан 30 November 2019 в 00:48
поделиться

Если вы не хотите сериализовать AJAX, я не могу придумать другого способа сделать то, что вы предлагаете. При этом я думаю, что то, что у вас есть, довольно хорошее, но вы можете немного очистить структуру, чтобы не засорять создаваемый вами объект данными инициализации.

Вот функция, которая может вам помочь:

function gate(fn, number_of_calls_before_opening) {
    return function() {
        arguments.callee._call_count = (arguments.callee._call_count || 0) + 1;
        if (arguments.callee._call_count >= number_of_calls_before_opening)
            fn.apply(null, arguments);
    };
}

Эта функция известна как функция высшего порядка - функция, которая принимает функции в качестве аргументов. Эта конкретная функция возвращает функцию, которая вызывает переданную функцию, когда она вызывалась number_of_calls_before_opening раз. Например:

var f = gate(function(arg) { alert(arg); }, 2);
f('hello');
f('world'); // An alert will popup for this call.

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

foo.bar = function() {
    var callback = gate(this.method, 2);
    sendAjax(new Request(), callback);
    sendAjax(new Request(), callback);
}

Второй обратный вызов, какой бы он ни был, гарантирует, что вызывается метод . Но это приводит к другой проблеме: функция gate вызывает переданную функцию без какого-либо контекста, то есть this будет ссылаться на глобальный объект, а не на объект, который вы создаете. Есть несколько способов обойти это: Вы можете закрыть this , присвоив ему псевдоним me или self . Или вы можете создать другую функцию более высокого порядка, которая делает именно это.

Вот как будет выглядеть первый случай:

foo.bar = function() {
    var me = this;        
    var callback = gate(function(a,b,c) { me.method(a,b,c); }, 2);

    sendAjax(new Request(), callback);
    sendAjax(new Request(), callback);
}

В последнем случае другая функция более высокого порядка будет выглядеть примерно так: :

function bind_context(context, fn) {
    return function() {
        return fn.apply(context, arguments);
    };
}

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

var obj = {};
var func = function(name) { this.name = name; };
var method = bind_context(obj, func);
method('Your Name!');
alert(obj.name); // Your Name!

Чтобы представить это в перспективе, ваш код будет выглядеть следующим образом:

foo.bar = function() {
    var callback = gate(bind_context(this, this.method), 2);

    sendAjax(new Request(), callback);
    sendAjax(new Request(), callback);
}

В любом случае, как только вы '

13
ответ дан 30 November 2019 в 00:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: