Ouvi falar de uma palavra-chave "yield" em JavaScript, mas achei uma documentação muito ruim. Alguém pode me explicar (ou recomendar um site que explique) seu uso e para que é utilizado?
javascript
yield
keyword
mck89
fonte
fonte
Respostas:
A documentação MDN é muito boa, IMO.
fonte
Resposta tardia, provavelmente todo mundo sabe
yield
agora, mas chegou uma documentação melhor.Adaptando um exemplo de "Javascript's Future: Generators", de James Long, para o padrão oficial Harmony:
Então
yield
é comoreturn
: você recebe algo de volta.return x
retorna o valor dex
, masyield x
retorna uma função, que fornece um método para iterar em direção ao próximo valor. Útil se você tiver um procedimento com uso intensivo de memória que talvez queira interromper durante a iteração.fonte
function* foo(x){
não*
. Se você precisa ou não, depende do tipo de futuro que você está retornando. Os detalhes são longos: o GvR explica para a implementação do Python , na qual a implementação do Javascript é modelada. O usofunction *
sempre estará correto, embora em alguns casos um pouco mais sobrecarga do quefunction
comyield
.function *
eyield
, e adicionou o erro entre aspas ("Um erro inicial é gerado se uma expressão de rendimento ou rendimento * ocorrer em uma função não geradora"). Mas, a implementação original do Javascript 1.7 no Firefox não exigia o*
. Resposta atualizada em conformidade. Obrigado!É realmente simples, é assim que funciona
yield
A palavra-chave simplesmente ajuda a pausar e retomar uma função a qualquer momento de forma assíncrona .Tome esta função simples de gerador :
Até você chamar o _process.next (), ele não executará as 2 primeiras linhas de código, e o primeiro rendimento fará uma pausa na função. Para retomar a função até o próximo ponto de pausa ( palavra-chave yield ), você precisa chamar _process.next () .
Mas enquanto o yield realiza essa pausa e retoma os comportamentos, ele também pode retornar alguns resultados , de
{value: any, done: boolean}
acordo com a função anterior, não emitimos nenhum valor. Se explorarmos a saída anterior, ela mostrará o mesmo{ value: undefined, done: false }
com o valor indefinido .Permite digitar a palavra-chave yield. Opcionalmente, você pode adicionar expressão e definir um valor opcional padrão . (Sintaxe oficial do documento)
expressão : Valor a ser retornado da função do gerador
rv : Retorna o valor opcional que passou para o método next () do gerador
Tente agora
Usos
Referências:
fonte
Simplificando / elaborando a resposta de Nick Sotiros (o que eu acho incrível), acho que é melhor descrever como alguém começaria a codificar
yield
.Na minha opinião, a maior vantagem do uso
yield
é que ele eliminará todos os problemas de retorno de chamada aninhados que vemos no código. É difícil ver como, a princípio, foi por isso que decidi escrever essa resposta (para mim e para outras pessoas!)A maneira como faz isso é introduzindo a idéia de uma co-rotina, que é uma função que pode parar / pausar voluntariamente até conseguir o que precisa. Em javascript, isso é indicado por
function*
. Somentefunction*
funções podem ser usadasyield
.Aqui está um javascript típico:
Isso é desajeitado porque agora todo o seu código (que obviamente precisa aguardar essa
loadFromDB
ligação) precisa estar dentro desse retorno de chamada feio. Isso é ruim por alguns motivos ...})
que precisa acompanhar em todos os lugaresfunction (err, result)
jargão extraresult
Por outro lado, com
yield
, tudo isso pode ser feito em uma linha com a ajuda da boa estrutura co-rotineira.E agora sua função principal renderá sempre que necessário quando precisar esperar que variáveis e coisas sejam carregadas. Mas agora, para executar isso, você precisa chamar uma função normal (não relacionada à corotina). Uma estrutura co-rotineira simples pode corrigir esse problema e tudo o que você precisa fazer é executar o seguinte:
E o começo é definido (da resposta de Nick Sotiro)
E agora, você pode ter um código bonito que é muito mais legível, fácil de excluir e sem necessidade de mexer com recuos, funções etc.
Uma observação interessante é que, neste exemplo,
yield
na verdade é apenas uma palavra-chave que você pode colocar antes de uma função com retorno de chamada.Imprimia "Olá Mundo". Assim, você pode realmente transformar qualquer função de retorno de chamada usando
yield
simplesmente criando a mesma assinatura de função (sem o cb) e retornando da seguintefunction (cb) {}
forma:Felizmente, com esse conhecimento, você pode escrever um código mais limpo e legível, fácil de excluir !
fonte
function*
é apenas uma função regular sem rendimento?function *
é uma função que contém rendimento. É uma função especial chamada gerador.yield
qualquer lugar, tenho certeza de que isso faz mais sentido do que os retornos de chamada, mas não vejo como isso é mais legível do que os retornos de chamada.Para dar uma resposta completa:
yield
está funcionando de maneira semelhante areturn
, mas em um gerador.Quanto ao exemplo comum, isso funciona da seguinte maneira:
Mas há também um segundo objetivo da palavra-chave yield. Pode ser usado para enviar valores ao gerador.
Para esclarecer, um pequeno exemplo:
Isso funciona, conforme o valor
2
é atribuídoy
, enviando-o ao gerador, depois que ele parou no primeiro rendimento (que retornou0
).Isso nos permite fazer algumas coisas realmente descoladas. (procure corotina)
fonte
É usado para geradores de iteradores. Basicamente, ele permite que você faça uma sequência (potencialmente infinita) usando código de procedimento. Veja a documentação do Mozilla .
fonte
yield
também pode ser usado para eliminar o inferno de retorno de chamada, com uma estrutura de corotina.fonte
Gerador de sequência de Fibonacci usando a palavra-chave yield.
fonte
Yeild
A palavra-chave na função javaScript o torna gerador,o que é gerador em javaScript?
Os geradores de significado nos ajudam a trabalhar de forma assíncrona com os iteradores de ajuda. Agora, o que são os iteradores de hack? realmente?
de onde o iterador nos ajuda a acessar o item um de cada vez? nos ajuda a acessar itens através das funções do gerador,
funções geradoras são aquelas nas quais usamos
yeild
palavras-chave, rendimento palavra-chave nos ajuda a pausar e retomar a execução da funçãoaqui está um exemplo rápido
deixe-me explicar rapidamente o que está acontecendo
você notou que a execução está sendo pausada em cada
yeild
palavra - chave e podemos acessar primeiroyield
com a ajuda do iterador.next()
isso itera para todas as
yield
palavras-chave uma de cada vez e, em seguida, retorna indefinido quando não há maisyield
palavras - chave em palavras simples. Você pode dizer que ayield
palavra-chave é um ponto de interrupção em que a função é interrompida a cada vez e é retomada apenas quando é chamada pelo iteradorpara o nosso caso:
_getMeDrink.next()
este é um exemplo de iterador que está nos ajudando a acessar cada ponto de interrupção na funçãoExemplo de Geradores:
async/await
se você ver a implementação de
async/await
você verá quegenerator functions & promises
são usados para fazer oasync/await
trabalhopor favor, aponte todas as sugestões são bem-vindas
fonte
Dependência entre chamadas assíncronas em javascript.
Outro bom exemplo de como o rendimento pode ser usado.
fonte
Antes de aprender sobre o rendimento, você precisa conhecer os geradores. Geradores são criados usando a
function*
sintaxe. As funções do gerador não executam código, mas retornam um tipo de iterador chamado gerador. Quando um valor é fornecido usando onext
método, a função do gerador continua em execução até encontrar uma palavra-chave yield. Usaryield
retorna um objeto contendo dois valores, um é o valor e o outro é feito (booleano). O valor pode ser uma matriz, objeto etc.fonte
Um exemplo simples:
fonte
Também estou tentando entender a palavra-chave yield. Com base no meu entendimento atual, no gerador, a palavra-chave yield funciona como uma alternância de contexto da CPU. Quando a declaração de rendimento é executada, todos os estados (por exemplo, variáveis locais) são salvos.
Além disso, um objeto de resultado direto será retornado ao chamador, como {value: 0, done: false}. O chamador pode usar esse objeto de resultado para decidir se deseja 'ativar' o gerador novamente chamando next () (chamar next () é para iterar a execução).
Outra coisa importante é que ele pode definir um valor para uma variável local. Este valor pode ser passado pelo chamador 'next ()' ao 'acordar' o gerador. por exemplo, it.next ('valueToPass'), assim: "resultValue = yield slowQuery (1);" Assim como ao ativar uma próxima execução, o chamador pode injetar algum resultado em execução na execução (injetando-o na variável local). Assim, para esta execução, existem dois tipos de estado:
o contexto que foi salvo na última execução.
Os valores injetados pelo gatilho desta execução.
Portanto, com esse recurso, o gerador pode classificar várias operações assíncronas. O resultado da primeira consulta assíncrona será passado para a segunda, definindo a variável local (resultValue no exemplo acima). A segunda consulta assíncrona só pode ser acionada pela resposta da primeira consulta assíncrona. Em seguida, a segunda consulta assíncrona pode verificar o valor da variável local para decidir as próximas etapas, porque a variável local é um valor injetado da resposta da primeira consulta.
As dificuldades das consultas assíncronas são:
inferno de retorno de chamada
perda de contexto, a menos que sejam transmitidos como parâmetros no retorno de chamada.
rendimento e gerador podem ajudar em ambos.
Sem rendimento e gerador, para classificar várias consultas assíncronas, é necessário um retorno de chamada aninhado com parâmetros como contexto, o que não é fácil de ler e manter.
Abaixo está um exemplo de consultas assíncronas encadeadas que são executadas com o nodejs:
Abaixo está o resultado atual:
+++++++++++ start +++++++++++
query1 0
+++++++++++ end +++++++++++
query2 1
query4 0
O padrão de estado abaixo pode fazer o mesmo no exemplo acima:
A seguir, o resultado da execução:
+++++++++++ start +++++++++++
query1 0
+++++++++++ end +++++++++++
query2 1
query4 0
fonte
não esqueça a sintaxe muito útil do 'x do gerador' para percorrer o gerador. Não é necessário usar a função next ().
fonte