Это типичная ситуация в node.js:
asyncFunction(arguments, callback);
Когда asynFunction
завершается, обратный вызов
получает называется. Проблема, которую я вижу с этим шаблоном, заключается в том, что если asyncFunction
никогда не завершается (и asynFunction
не имеет встроенной системы тайм-аута), то обратный вызов
никогда не будет вызван. Хуже того, похоже, что обратный вызов
не может определить, что asynFunction
никогда не вернется.
Я хочу реализовать «тайм-аут», при котором, если обратный вызов
не был вызван asyncFunction
в течение 1 секунды, то обратный вызов
автоматически вызывается с предположением что asynFunction
вызвала ошибку. Что это за стандартный способ?
Я не знаком ни с какими библиотеками, которые делают это, но не сложно подключить себя.
// 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();
}
});
Вы можете сделать что-то вроде этого:
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));
Но обратите внимание на следующее:
Тайм-аут начинается сразу же после вызова ensureExecution
, поэтому вы не можете кэшировать ссылку на эту функцию.
Аргументы, переданные обратному вызову, будут отличаться. Например, asyncFunction
может передать некоторые аргументы callback
в случае успеха, но если функция вызывается по таймауту, никакие аргументы не будут переданы. Вы должны помнить это. Вы также можете предоставить аргументы по умолчанию, с которыми функция должна вызываться в этом случае:
function ensureExecution(func, timeout, args, this_obj) {
// ...
timer = setTimeout(function() {
run.apply(this_obj, args);
}, timeout);
//...
}