Я копаюсь в функции async / await узла 7 и продолжаю натыкаться на такой код
function getQuote() {
let quote = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
return quote;
}
async function main() {
try {
var quote = await getQuote();
console.log(quote);
} catch (error) {
console.error(error);
}
}
main();
Кажется, это единственная возможность разрешить / отклонить или вернуть / выбросить с помощью async / await, однако v8 не оптимизирует код в блоках try / catch ?!
Есть ли альтернативы?
Ответы:
альтернативы
Альтернатива этому:
было бы что-то вроде этого, явно используя обещания:
или что-то вроде этого, используя стиль передачи продолжения:
Оригинальный пример
Что делает ваш исходный код, так это приостанавливает выполнение и ждет, пока обещание, возвращенное от, не
getQuote()
будет выполнено. Затем он продолжает выполнение и записывает возвращенное значение,var quote
а затем печатает его, если обещание было разрешено, или генерирует исключение и запускает блок catch, который печатает ошибку, если обещание было отклонено.Вы можете сделать то же самое, используя Promise API напрямую, как во втором примере.
Производительность
Теперь о представлении. Давай проверим!
Я только что написал этот код -
f1()
выдает1
как возвращаемое значение,f2()
выдает1
как исключение:Теперь давайте вызовем один и тот же код миллион раз, сначала с помощью
f1()
:А потом перейдем
f1()
кf2()
:Вот результат, который я получил
f1
:Вот для чего я получил
f2
:Кажется, что вы можете сделать что-то вроде 2 миллионов бросков в секунду в одном однопоточном процессе. Если вы делаете больше, возможно, вам стоит об этом побеспокоиться.
Резюме
Я бы не стал беспокоиться о подобных вещах в Node. Если подобные вещи будут использоваться часто, то в конечном итоге они будут оптимизированы командами V8, SpiderMonkey или Chakra, и все последуют за ними - это не похоже на то, чтобы не оптимизировать в принципе, это просто не проблема.
Даже если он не оптимизирован, я все равно буду утверждать, что если вы максимизируете свой ЦП в Node, вам, вероятно, следует писать свои числа на C - среди прочего, для этого предназначены нативные надстройки. Или, может быть, для этой работы лучше подошли бы такие вещи, как node.native , чем Node.js.
Мне интересно, какой вариант использования должен вызывать так много исключений. Обычно выдача исключения вместо возврата значения является исключением.
источник
try catch
, а не от выброса исключения. Хотя цифры небольшие, согласно вашим тестам, он почти в 10 раз медленнее, что немаловажно.Альтернатива, аналогичная обработке ошибок в Golang
Поскольку async / await использует обещания под капотом, вы можете написать небольшую служебную функцию, подобную этой:
Затем импортируйте его, когда вам нужно отловить какие-либо ошибки, и оберните свою асинхронную функцию, которая возвращает обещание с ней.
источник
Альтернативой блоку try-catch является await-to-js lib. Я часто им пользуюсь. Например:
Этот синтаксис намного чище по сравнению с try-catch.
источник
В качестве альтернативы вместо объявления возможной переменной для хранения ошибки вверху вы можете сделать
Хотя это не сработает, если будет выдано что-то вроде ошибки TypeError или Reference. Вы можете убедиться, что это обычная ошибка, но с
Я предпочитаю обернуть все в большой блок try-catch, где создается несколько обещаний, что может затруднить обработку ошибки специально для создавшего ее обещания. Альтернативой является несколько блоков try-catch, которые я считаю одинаково громоздкими
источник
Более чистой альтернативой будет следующее:
Из-за того, что каждая асинхронная функция технически является обещанием
Вы можете добавлять уловки к функциям при их вызове с помощью await
Нет необходимости в try catch, так как все ошибки обещаний обрабатываются, и у вас нет ошибок кода, вы можете пропустить это в родительском элементе !!
Допустим, вы работаете с mongodb, если есть ошибка, вы можете предпочесть обработать ее в вызывающей ее функции, а не создавать оболочки или использовать уловки try.
источник
Я бы хотел так сделать :)
Это похоже на обработку ошибки с
co
источник
await
!catch
По моему опыту, поступать таким образом опасно. Будет обнаружена любая ошибка, возникшая во всем стеке, а не только ошибка из этого обещания (что, вероятно, не то, что вам нужно).Второй аргумент обещания - это уже обратный вызов отказа / отказа. Лучше и безопаснее использовать это вместо этого.
Вот однострочный текст, который я написал, чтобы справиться с этим:
источник