Estou cavando no recurso assíncrono / aguardar do nó 7 e continuo encontrando códigos como este
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();
Esta parece ser a única possibilidade de resolver / rejeitar ou retornar / lançar com async / await, no entanto, a v8 não otimiza o código dentro dos blocos try / catch ?!
Existem alternativas?
node.js
async-await
ecmascript-2017
Patrick
fonte
fonte
Respostas:
Alternativas
Uma alternativa para isso:
seria algo assim, usando promessas explicitamente:
ou algo assim, usando o estilo de passagem de continuação:
Exemplo original
O que o seu código original faz é suspender a execução e esperar que a promessa retornada por
getQuote()
se cumpra. Em seguida, ele continua a execução e grava o valor retornado emvar quote
e o imprime se a promessa foi resolvida, ou lança uma exceção e executa o bloco catch que imprime o erro se a promessa foi rejeitada.Você pode fazer a mesma coisa usando a API Promise diretamente, como no segundo exemplo.
atuação
Agora, para a performance. Vamos testar!
Acabei de escrever este código -
f1()
dá1
como um valor de retorno,f2()
lança1
como uma exceção:Agora vamos chamar o mesmo código milhões de vezes, primeiro com
f1()
:E então vamos mudar
f1()
paraf2()
:Este é o resultado que obtive para
f1
:Isso é o que eu tenho para
f2
:Parece que você pode fazer algo como 2 milhões de jogadas por segundo em um processo de thread único. Se você estiver fazendo mais do que isso, talvez precise se preocupar com isso.
Resumo
Eu não me preocuparia com coisas assim em Node. Se coisas assim forem muito usadas, então serão otimizadas eventualmente pelas equipes V8 ou SpiderMonkey ou Chakra e todos irão seguir - não é como se não fosse otimizado como um princípio, simplesmente não é um problema.
Mesmo se não estiver otimizado, eu ainda diria que se você está maximizando sua CPU no Node, então você provavelmente deve escrever seu cálculo de número em C - é para isso que servem os addons nativos, entre outras coisas. Ou talvez coisas como node.native sejam mais adequadas para o trabalho do que Node.js.
Estou me perguntando qual seria um caso de uso que precisa lançar tantas exceções. Normalmente, lançar uma exceção em vez de retornar um valor é, bem, uma exceção.
fonte
try catch
, não de lançar uma exceção. Embora os números sejam pequenos, é quase 10 vezes mais lento de acordo com seus testes, o que não é insignificante.Alternativa semelhante ao tratamento de erros em Golang
Como async / await usa promessas por baixo do capô, você pode escrever uma pequena função de utilitário como esta:
Em seguida, importe-o sempre que precisar detectar alguns erros e envolva sua função assíncrona, que retorna uma promessa com ela.
fonte
Uma alternativa para o bloco try-catch é await-to-js lib. Costumo usá-lo. Por exemplo:
Essa sintaxe é muito mais limpa quando comparada ao try-catch.
fonte
Alternativamente, em vez de declarar uma possível var para conter um erro no topo, você pode fazer
Embora isso não funcione se algo como um erro TypeError ou Reference for lançado. Você pode garantir que é um erro regular, embora com
Minha preferência por isso é envolver tudo em um grande bloco try-catch, onde há várias promessas sendo criadas, o que pode tornar complicado lidar com o erro especificamente para a promessa que o criou. Com a alternativa de vários blocos try-catch, que considero igualmente complicados
fonte
Uma alternativa mais limpa seria a seguinte:
Devido ao fato de que toda função assíncrona é tecnicamente uma promessa
Você pode adicionar capturas às funções ao chamá-las com await
Não há necessidade de try catch, já que todos os erros de promessas são tratados e você não tem erros de código, você pode omitir isso no pai !!
Digamos que você esteja trabalhando com mongodb; se houver um erro, você pode preferir manipulá-lo na função que o chama do que criando wrappers ou usando try catches.
fonte
Eu gostaria de fazer assim :)
É semelhante a lidar com erros com
co
fonte
await
!catch
fazer isso, em minha experiência, é perigoso. Qualquer erro lançado em toda a pilha será detectado, não apenas um erro dessa promessa (que provavelmente não é o que você deseja).O segundo argumento para uma promessa já é um retorno de rejeição / falha. É melhor e mais seguro usar isso.
Aqui está uma linha de texto typesafe que escrevi para lidar com isso:
fonte