2014-01-14 3 views
0

У меня есть рабочий класс, который имеет множество различных методов утилиты и испускает сообщения error, когда есть проблема в любом месте выполнения. Благодаря NodeJS магии, error сообщения являются особенными, и если ничего не слушает их, они превратились в выброшенных ошибки, так что я в настоящее время сделать:Ошибка в событии ошибки NodeJS?

var myWorkerFunction = function(input) { 
    var w = myFactory(); 
    try { 
    w.dothis(); 
    w.dothat(input); 
    w.hokeypokey(); 
    return w.finalize(); 
    } catch(e) { 
    return false; 
    } 
} 

Что интересно, хотя, возможно, чтобы избежать попробовать/catch полностью? Документация NodeJS, по-видимому, указывает на то, что лучше избегать повторного броска пойманного исключения (я не делаю никаких проверок здесь, чтобы убедиться, что на самом деле логика моего работника выбрала исключение, а не критическую ошибку из Node).

Так что я хотел бы сделать что-то вроде:

var myWorkerFunction = function(input) { 
    var w = myFactory(); 
    w.on('error', function() { 
    // How to tell caller of myWorkerFunction() I failed, 
    // and stop the rest of the myWorkerFunction function? (return false) 
    }); 
    w.dothis(); 
    w.dothat(input); 
    w.hokeypokey(); 
    return w.finalize(); 
} 

Но как вызвать, что «возвращение» для myWorkerFunction внутри этой функции прослушивателя событий? Я мог бы написать myWorkerFunction сообщение об ошибке, но это просто ударяет банку на следующий уровень и не останавливает выполнение рабочего сценария (т. Е. Если dothis() терпит неудачу, не продолжайте и звоните dothat(input)). Существует ли схема программирования для таких ситуаций?

EDIT: один решение, которое я мог бы придумать что-то вроде:

var myWorkerFunction = function(input) { 
    var w = myFactory(); 
    var hasFailed = false; 
    w.on('error', function() { 
    hasFailed = true; 
    }); 
    w.dothis(); 
    if (hasFailed) return fa;se 
    w.dothat(input); 
    if (hasFailed) return false; 
    w.hokeypokey(); 
    if (hasFailed) return false; 
    var out = w.finalize(); 
    if (hasFailed) return false; 
    return out; 
} 

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

+0

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

+0

@adeneo: не могли бы вы привести пример кода, как это сделать? – MidnightLightning

ответ

0

Пара мыслей об этом. Сначала вы можете взглянуть на Caolan McMahon в порядке async nodejs library, потому что похоже, что вы изобретаете управление потоком, которое будет хорошо обрабатываться с помощью «async.waterfall».

Если вы не чувствуете, что это хорошо подходит вам - после принятого вами шаблона вы можете публиковать события по завершении каждого шага (см. «Сделанные» события в примере ниже). Это позволит вам прослушивать эти события как указание на отсутствие ошибки и что имеет смысл перейти к следующему шагу. Позвольте «финализировать» взять необязательную ошибку, чтобы позволить вашему работнику дифференцировать нормальное и аномальное завершение. Это не проверено, но вот что может выглядеть примерно так:

var myWorkerFunction = function(input) { 
    var w = myFactory(); 
    w.on('error', function(error) { 
    // Handle error, log whatever - and finalize with an error? 
    w.finalize(error); 
    }); 
    w.on('doneWithThis', function() { 
    w.dothat(input); 
    }); 
    w.on('doneWithThat', function() { 
    w.hokeypokey(); 
    }); 
    w.on('doneWithHokeypokey', function() { 
    w.finalize(); 
    }); 

    w.dothis(); //starts the ball rolling. 
} 
+0

Хороший совет; в течение двух лет с тех пор, как я опубликовал это, я узнал о классе 'async.waterfall' и использовал это, когда я управляю библиотекой (например, в том случае, когда мои рабочие методы являются моими). Поскольку дорожная карта javascript движется в направлении Promises в качестве родного механика, то, когда рабочие методы возвращают обещания, которые разрешают, когда это будет сделано, было бы другим средством для этого. – MidnightLightning

+0

@MidnightLightning разумно отметить это как правильный ответ? – darrin

Смежные вопросы