Zagłębiam się w funkcję async / await w węźle 7 i wciąż natknę się na taki kod
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();
Wydaje się, że jest to jedyna możliwość rozwiązania / odrzucenia lub zwrotu / wyrzucenia z async / await, jednak wersja 8 nie optymalizuje kodu w blokach try / catch ?!
Czy są alternatywy?
node.js
async-await
ecmascript-2017
Patrick
źródło
źródło
Odpowiedzi:
Alternatywy
Alternatywa dla tego:
byłoby coś takiego, używając wyraźnie obietnic:
lub coś takiego, używając stylu przekazywania kontynuacji:
Oryginalny przykład
To, co robi twój oryginalny kod, to wstrzymanie wykonania i oczekiwanie na
getQuote()
rozliczenie zwróconej przez niego obietnicy . Następnie kontynuuje wykonywanie i zapisuje zwróconą wartość do,var quote
a następnie drukuje ją, jeśli obietnica została rozwiązana, lub zgłasza wyjątek i uruchamia blok catch, który wyświetla błąd, jeśli obietnica została odrzucona.Możesz zrobić to samo używając Promise API bezpośrednio, jak w drugim przykładzie.
Występ
Teraz do wykonania. Przetestujmy to!
Właśnie napisałem ten kod -
f1()
podaje1
jako wartość zwracaną,f2()
wyrzuca1
jako wyjątek:Teraz wywołajmy ten sam kod milion razy, najpierw
f1()
:A potem przejdźmy
f1()
dof2()
:Oto wynik, który otrzymałem za
f1
:Za to mam
f2
:Wygląda na to, że możesz zrobić około 2 milionów rzutów na sekundę w jednym procesie jednowątkowym. Jeśli robisz więcej niż to, być może będziesz musiał się tym martwić.
Podsumowanie
Nie martwiłbym się takimi rzeczami w Node. Jeśli takie rzeczy są często używane, zostaną ostatecznie zoptymalizowane przez zespoły V8, SpiderMonkey lub Chakra i wszyscy będą podążać - nie jest tak, że nie jest zoptymalizowany jako zasada, po prostu nie stanowi problemu.
Nawet jeśli nie jest zoptymalizowany, nadal argumentowałbym, że jeśli maksymalizujesz swój procesor w Node, prawdopodobnie powinieneś napisać chrupanie liczb w C - między innymi do tego służą natywne dodatki. A może rzeczy takie jak node.native byłyby lepiej dostosowane do tego zadania niż Node.js.
Zastanawiam się, jaki byłby przypadek użycia, który wymaga rzucania tak wielu wyjątków. Zwykle zgłoszenie wyjątku zamiast zwracania wartości jest, no cóż, wyjątkiem.
źródło
try catch
, a nie z wyrzucenia wyjątku. Chociaż liczby są małe, według twoich testów jest prawie 10 razy wolniejsze, co nie jest bez znaczenia.Alternatywa podobna do obsługi błędów w Golangu
Ponieważ async / await używa obietnic pod maską, możesz napisać małą funkcję użytkową, taką jak ta:
Następnie zaimportuj go, gdy chcesz wychwycić jakieś błędy, i zawiń swoją funkcję asynchroniczną, która zwraca z nią obietnicę.
źródło
Alternatywą dla bloku try-catch jest await-to-js lib. Często go używam. Na przykład:
Ta składnia jest znacznie czystsza w porównaniu do try-catch.
źródło
Alternatywnie, zamiast deklarować możliwą zmienną, aby zawierała błąd na górze, możesz zrobić
Chociaż to nie zadziała, jeśli zostanie wyrzucony błąd typu TypeError lub Reference. Możesz jednak upewnić się, że jest to zwykły błąd
Preferuję to zawijanie wszystkiego w duży blok próbny, w którym jest tworzonych wiele obietnic, co może utrudnić obsługę błędu specjalnie dla obietnicy, która go utworzyła. Alternatywą jest wiele bloków try-catch, które uważam za równie kłopotliwe
źródło
Czystsza alternatywa byłaby następująca:
Ze względu na fakt, że każda funkcja asynchroniczna jest technicznie obietnicą
Możesz dodawać zaczepy do funkcji, wywołując je za pomocą await
Nie ma potrzeby próbowania złapania, ponieważ wszystkie błędy obietnic są obsługiwane, a nie masz błędów w kodzie, możesz to pominąć w nadrzędnym!
Powiedzmy, że pracujesz z mongodb, jeśli wystąpi błąd, możesz go obsłużyć w funkcji wywołującej go niż tworzenie opakowań lub używanie try catch.
źródło
Chciałbym to zrobić w ten sposób :)
Jest to podobne do obsługi błędów w programie
co
źródło
await
!catch
z doświadczenia wiem, że takie postępowanie jest niebezpieczne. Każdy błąd wyrzucony w całym stosie zostanie wychwycony, a nie tylko błąd z tej obietnicy (która prawdopodobnie nie jest tym, czego chcesz).Drugim argumentem obietnicy jest już wywołanie zwrotne dotyczące odrzucenia / niepowodzenia. Zamiast tego lepiej i bezpieczniej jest z tego korzystać.
Oto bezpieczna dla maszynisty jednowierszowa, którą napisałem, aby sobie z tym poradzić:
źródło