Se eu precisar chamar 3 http API em ordem sequencial, qual seria a melhor alternativa para o seguinte código:
http.get({ host: 'www.example.com', path: '/api_1.php' }, function(res) {
res.on('data', function(d) {
http.get({ host: 'www.example.com', path: '/api_2.php' }, function(res) {
res.on('data', function(d) {
http.get({ host: 'www.example.com', path: '/api_3.php' }, function(res) {
res.on('data', function(d) {
});
});
}
});
});
}
});
});
}
node.js
synchronization
Howard
fonte
fonte
sync-request
biblioteca, o que é uma boa resposta ao título desta pergunta, mas não uma resposta para o que o código da pergunta implica. A resposta abaixo sobre Promessas é uma resposta melhor para isso. O que você quis dizer?Respostas:
Usando adiados como
Futures
.Se você precisa passar o escopo adiante, faça algo assim
fonte
Também gosto da solução da Raynos, mas prefiro uma biblioteca de controle de fluxo diferente.
https://github.com/caolan/async
Dependendo se você precisa dos resultados em cada função subsequente, eu usaria série, paralelo ou cascata.
Séries quando precisam ser executadas em série, mas você não precisa necessariamente dos resultados em cada chamada de função subsequente.
Paralelo, se eles podem ser executados em paralelo, você não precisa dos resultados de cada um durante cada função paralela e precisa de um retorno de chamada quando todos tiverem sido concluídos.
Waterfall se você quiser transformar os resultados em cada função e passar para a próxima
fonte
Você pode fazer isso usando minha biblioteca de nó comum :
fonte
require(...).HttpClient is not a constructor
pedido de sincronização
De longe, o mais fácil que encontrei e usei é o sync-request e ele suporta o node e o navegador!
É isso, sem configuração maluca, sem instalações complexas de lib, embora tenha um fallback de lib. Apenas funciona. Tentei outros exemplos aqui e fiquei perplexo quando havia muita configuração extra para fazer ou as instalações não funcionavam!
Notas:
O exemplo que sync-request usa não funciona bem quando você usa
res.getBody()
, tudo o que get body faz é aceitar uma codificação e converter os dados de resposta. Basta fazer emres.body.toString(encoding)
vez disso.fonte
Eu usaria uma função recursiva com uma lista de apis
editar: solicitar versão
editar: solicitar / versão assíncrona
fonte
Parece que as soluções para este problema não têm fim, aqui está mais uma :)
http://alexeypetrushin.github.com/synchronize
fonte
Outra possibilidade é configurar um retorno de chamada que rastreie as tarefas concluídas:
Em seguida, basta atribuir um ID para cada um e você pode definir seus requisitos para quais tarefas devem ser concluídas antes de fechar a conexão.
Ok, não é bonito. É apenas outra maneira de fazer chamadas sequenciais. É uma pena que o NodeJS não forneça as chamadas síncronas mais básicas. Mas eu entendo o que é a atração para a assincronicidade.
fonte
use sequenty.
sudo npm install sequenty
ou
https://github.com/AndyShin/sequenty
muito simples.
também você pode usar um loop como este:
fonte
Usar a biblioteca de solicitações pode ajudar a minimizar o problema:
Mas para o máximo de grandiosidade, você deve tentar alguma biblioteca de fluxo de controle como Step - ela também permitirá que você paralelize as solicitações, presumindo que seja aceitável:
fonte
A partir de 2018 e usando módulos ES6 e Promises, podemos escrever uma função como esta:
e então em outro módulo
O código precisa ser executado em um contexto assíncrono (usando a
async
palavra-chave)fonte
Existem muitas bibliotecas de fluxo de controle - eu gosto do conseq (... porque eu o escrevi). Além disso,
on('data')
pode disparar várias vezes, então use uma biblioteca de wrapper REST como restler .fonte
Isso foi bem respondido por Raynos. Ainda assim, houve mudanças na biblioteca de sequências desde que a resposta foi postada.
Para fazer a sequência funcionar, siga este link: https://github.com/FuturesJS/sequence/tree/9daf0000289954b85c0925119821752fbfb3521e .
É assim que você pode fazer isso funcionar depois de
npm install sequence
:fonte
Esta é minha versão de @ andy-shin sequencialmente com argumentos em array em vez de index:
fonte
... 4 anos depois ...
Aqui está uma solução original com o framework Danf (você não precisa de nenhum código para este tipo de coisas, apenas algumas configurações):
Se você quiser ser ainda mais curto, pode usar um processo de coleta:
Dê uma olhada na visão geral da estrutura para obter mais informações.
fonte
Cheguei aqui porque precisava limitar a taxa de http.request (~ 10k consultas de agregação para pesquisa elástica para construir um relatório analítico). O seguinte apenas sufocou minha máquina.
Minhas URLs são muito simples, então isso pode não se aplicar trivialmente à pergunta original, mas acho que é potencialmente aplicável e vale a pena escrever aqui para leitores que chegam aqui com problemas semelhantes aos meus e que querem uma solução JavaScript trivial sem biblioteca.
Meu trabalho não dependia da ordem e minha primeira abordagem para resolver isso foi envolvê-lo em um script de shell para fragmentá-lo (porque sou novo em JavaScript). Isso foi funcional, mas não satisfatório. Minha resolução de JavaScript no final era fazer o seguinte:
Parece uma recursão mútua entre collect e get_top . Não tenho certeza se está em vigor porque o sistema é assíncrono e a função collect é concluída com um retorno de chamada armazenado para o evento em. ('Fim' .
Acho que é geral o suficiente para se aplicar à pergunta original. Se, como no meu cenário, a sequência / conjunto for conhecido, todos os URLs / chaves podem ser colocados na pilha em uma etapa. Se eles são calculados conforme você avança, a função on ('end' pode enviar o próximo url na pilha antes de get_top () . Se houver, o resultado tem menos aninhamento e pode ser mais fácil de refatorar quando a API que você está chamando alterar.
Eu percebo que isso é efetivamente equivalente à versão recursiva simples do @generalhenry acima (então eu votei a favor!)
fonte
Super Solicitação
Este é outro módulo síncrono baseado em solicitações e usa promessas. Super simples de usar, funciona bem com testes de mocha.
npm install super-request
fonte
Este código pode ser usado para executar uma série de promessas de forma síncrona e sequencial, após a qual você pode executar seu código final na
.then()
chamada.fonte
Na verdade, consegui exatamente o que você (e eu) queríamos, sem o uso de await, Promises ou inclusões de qualquer biblioteca (externa) (exceto a nossa).
Veja como fazer:
Vamos fazer um módulo C ++ para ir com node.js, e essa função de módulo C ++ fará a solicitação HTTP e retornará os dados como uma string, e você pode usar isso diretamente fazendo:
VOCÊ ESTÁ PRONTO para começar?
Passo 1: crie uma nova pasta em outro lugar do seu computador, estamos usando esta pasta apenas para construir o arquivo module.node (compilado do C ++), você pode movê-lo mais tarde.
Na nova pasta (coloquei a minha em mynewFolder / src para organização):
então
agora faça 2 novos arquivos: 1, chamado something.cpp e para colocar este código nele (ou modifique-o se quiser):
Agora faça um novo arquivo no mesmo diretório chamado
something.gyp
e coloque (algo como) isto nele:Agora, no arquivo package.json, adicione:
"gypfile": true,
Agora: no console,
node-gyp rebuild
Se passar por todo o comando e disser "ok" no final sem erros, você está (quase) pronto para prosseguir, se não, deixe um comentário.
Mas se funcionar, vá para build / Release / cobypp.node (ou o que for chamado para você), copie-o para a pasta node.js principal e, em seguida, para node.js:
fonte