Реализация тайм-аутов для обратных вызовов node.js

Это типичная ситуация в node.js:

asyncFunction(arguments, callback);

Когда asynFunction завершается, обратный вызов получает называется. Проблема, которую я вижу с этим шаблоном, заключается в том, что если asyncFunction никогда не завершается (и asynFunction не имеет встроенной системы тайм-аута), то обратный вызов никогда не будет вызван. Хуже того, похоже, что обратный вызов не может определить, что asynFunction никогда не вернется.

Я хочу реализовать «тайм-аут», при котором, если обратный вызов не был вызван asyncFunction в течение 1 секунды, то обратный вызов автоматически вызывается с предположением что asynFunction вызвала ошибку. Что это за стандартный способ?

30
задан Randomblue 4 December 2011 в 18:58
поделиться

2 ответа

Я не знаком ни с какими библиотеками, которые делают это, но не сложно подключить себя.

// Setup the timeout handler
var timeoutProtect = setTimeout(function() {

  // Clear the local timer variable, indicating the timeout has been triggered.
  timeoutProtect = null;

  // Execute the callback with an error argument.
  callback({error:'async timed out'});

}, 5000);

// Call the async function
asyncFunction(arguments, function() {

  // Proceed only if the timeout handler has not yet fired.
  if (timeoutProtect) {

    // Clear the scheduled timeout handler
    clearTimeout(timeoutProtect);

    // Run the real callback.
    callback();
  }
});
24
ответ дан 28 November 2019 в 00:16
поделиться

Вы можете сделать что-то вроде этого:

function ensureExecution(func, timeout) {
    var timer, run, called = false;

    run = function() {   
        if(!called) {
            clearTimeout(timer);
            called = true;
            func.apply(this, arguments);
        }   
    };

    timer = setTimeout(run, timeout);
    return run;
}

Использование:

asyncFunction(arguments, ensureExecution(callback, 1000));

DEMO

Но обратите внимание на следующее:

  • Тайм-аут начинается сразу же после вызова ensureExecution, поэтому вы не можете кэшировать ссылку на эту функцию.

  • Аргументы, переданные обратному вызову, будут отличаться. Например, asyncFunction может передать некоторые аргументы callback в случае успеха, но если функция вызывается по таймауту, никакие аргументы не будут переданы. Вы должны помнить это. Вы также можете предоставить аргументы по умолчанию, с которыми функция должна вызываться в этом случае:

    function ensureExecution(func, timeout, args, this_obj) {
        // ...
        timer = setTimeout(function() {
            run.apply(this_obj, args);
        }, timeout);
        //...
    }
    
4
ответ дан 28 November 2019 в 00:16
поделиться
Другие вопросы по тегам:

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