Calc
calc é uma função assíncrona que queremos fazer análises (análise de desempenho). Por convenção, seu último parâmetro é um callback . Usamos calc como este:
calc (arg, (err, res) => console.log (err || res))
Talvez a maneira mais fácil de analisar o desempenho em uma função como calc seja adicionar uma lógica de tempo ao onde precisamos analisar:
const t0 = date.now () calc (arg, (err, res) => {const t1 = date.now () console.log (`log: time: $ {t1 = t0}`) console.log (err || res)}) No entanto, esta não é uma solução reutilizável. Toda vez que queremos cronometrar uma função, temos que introduzir um T0 no escopo externo e alterar callback para medir e registrar o tempo.
A maneira ideal para mim é ser capaz de cronometrar apenas envolvendo uma função assíncrona:
timeit (calc) (arg, (err, res) => console.log (err || res))
timeIt precisa ser capaz de executar a análise e registrar o tempo de execução para cada função assíncrona bem.
Observe que timeIt(calc) possui a mesma assinatura de função que a função CALC original, ou seja, eles aceitam os mesmos parâmetros e retornam o mesmo valor, apenas adiciona um recurso ao CALE (um recurso que pode ser o tempo gravado).
Calc e Timeit (Calc) podem ser substituídos um pelo outro a qualquer momento.
timeIt em si é uma função de ordem superior porque aceita uma função e retorna uma função. Em nosso exemplo, ele aceita uma função assíncrona de cálculo e retorna uma função com os mesmos parâmetros e valor de retorno que calc.
A seguir, mostra como implementamos a função Timeit:
const timeit = r.curry ((relatório, f) => (... args) => {const t0 = date.now () const nargs = r.init (args) const retorno = r.last (args) nargs.push ((... args) => {const t1 = date.now () callback (... ... f (... nargs)}) const timeit1 = timeit ((t, err, res) => console.log (`log: $ {err || res} produzido após: $ {t}`)) const calc = (x, x, z, z, retorno) => settimeout () => call (null, x * y / z, / z, z, z, rackback) => setTimeout () => console.log (err || res)) timeit1 (calc) (18, 7, 3, (err, res) => console.log (err || res)) Esta implementação timeIt aceita dois parâmetros:
Relatório: Uma função é usada para gerar resultados de análise
F: Função assíncrona que queremos fazer análises
timeIt1 é uma função conveniente e prática, apenas usa console.log para registrar os resultados da medição de tempo. Nós o definimos passando no parâmetro report para a função mais geral timeIt .
Atingimos a meta e agora podemos apenas embrulhar a função assíncrona no timeIt1 e o tempo é cronometrado:
timeit1 (calc) (18, 7, 3, (err, res) => console.log (err || res))
A função timeIt geral recebe uma função de retorno de chamada de report e uma função assíncrona e retorna uma nova função assíncrona. Essa função assíncrona possui os mesmos parâmetros e valor de retorno que a função original. Podemos usar isso:
timeit ((time, ... resultado) => // Relatório de chamada: Log the the time, assyncfunc) (parâmetros…, (... resultado) => // resultado da função assíncrona)
Agora vamos mergulhar na implementação do timeIt . Podemos simplesmente gerar uma função geral como timeIt1 , porque timeIt é coryilado usando R.curry .
Não pretendo discutir a coriculização neste post, mas o código a seguir demonstra o principal uso da coriculização:
const f = r.curry ((x, y) => x + y) f (1, 10) // == 11f (1) (10) // == 11CONST Plus1 = F (1) Plus1 (10) // == 11
Por outro lado, existem vários problemas com o Timeit implementado dessa maneira:
(... args) => {const t1 = date.now () retorno de chamada (... args) relatório (t1 - t0, ... args)} Esta é uma função anônima (também conhecida como lambda, retorno de chamada) que é chamada após a função original ser executada de forma assíncrona. O principal problema é que essa função não tem mecanismo para lidar com exceções. Se callback lançar uma exceção, report nunca será chamado.
Podemos adicionar uma try / catch a essa função lambda , mas a raiz do problema é que callback e report são duas funções void e elas não estão associadas. timeIt contém duas continuações ( report e callback ). Se apenas registrarmos o tempo de execução no console ou se tivermos certeza de que nem report nem callback lançarão exceções, tudo está bem. Mas se queremos executar algum comportamento com base nos resultados da análise (a chamada escala automática), precisamos fortalecer e esclarecer a sequência de continuação em nosso programa.
Ok, espero que o conteúdo completo deste artigo seja útil para o estudo e o trabalho de todos. Se você tiver alguma dúvida, pode deixar uma mensagem para se comunicar.