Parece que quase todo mundo faz solicitações assíncronas com XMLHttpRequest, mas obviamente o fato de haver a capacidade de fazer solicitações síncronas indica que pode haver um motivo válido para fazer isso. Então, qual seria esse motivo válido?
javascript
ajax
Darrell Brogdon
fonte
fonte
Respostas:
Eu acho que eles podem se tornar mais populares com o progresso dos padrões do HTML 5. Se um aplicativo da web tiver acesso a web workers, posso prever os desenvolvedores usando um web worker dedicado para fazer solicitações síncronas, como Jonathan disse, para garantir que uma solicitação aconteça antes da outra. Com a situação atual de um segmento, é um design menos do que ideal, pois bloqueia até que a solicitação seja concluída.
fonte
XHRs síncronos são úteis para salvar dados do usuário. Se você manipular o
beforeunload
evento, poderá fazer upload de dados para o servidor enquanto o usuário fecha a página.Se isso fosse feito usando a opção async, a página poderia fechar antes que a solicitação fosse concluída. Fazer isso de forma síncrona garante que a solicitação seja concluída ou falhe da maneira esperada.
fonte
Atualizar:
O que se segue sugeriu - mas não foi bem-sucedido no fornecimento - que com o advento de um melhor tratamento de solicitações assíncronas, realmente não há razão para usar solicitações síncronas, a menos que a intenção de bloquear propositalmente os usuários de fazer qualquer coisa até que uma solicitação seja concluída - parece malicioso: )
Embora isso possa parecer ruim, pode haver momentos em que é importante que uma solicitação (ou série de solicitações) ocorra antes de um usuário sair de uma página ou antes de uma ação ser realizada - bloquear a execução de outro código (por exemplo, impedir o botão Voltar) pode possivelmente reduza os erros / manutenção de um sistema mal projetado; Dito isto, nunca o vi em estado selvagem e insisto que deve ser evitado.
Bibliotecas, como a promessa , fingem sincronicidade ao encadear processos por meio de retornos de chamada. Isso atende à maioria das necessidades de desenvolvimento em que o desejo é ter eventos ordenados e não bloqueadores que permitam aos navegadores manter a capacidade de resposta para o usuário (UX bom).
Conforme declarado nos documentos do Mozilla, há casos em que você deve usar solicitações síncronas; no entanto, também listado é uma solução alternativa que usa beacon (não disponível no IE / Safari) para tais casos. Embora seja experimental, se chegar a ser aceito pelos padrões, pode colocar um prego no caixão de solicitação síncrona.
Você gostaria de realizar chamadas síncronas em qualquer tipo de processamento semelhante a uma transação ou onde quer que qualquer ordem de operação seja necessária.
Por exemplo, digamos que você queira personalizar um evento para desconectá-lo após tocar uma música. Se a operação de logout ocorrer primeiro, a música nunca será reproduzida. Isso requer a sincronização das solicitações.
Outro motivo seria ao trabalhar com um WebService, especialmente ao realizar matemática no servidor.
Poucas vezes uma chamada síncrona pode ser justificada em um exemplo comum do mundo real. Talvez ao clicar em login e, em seguida, clicar em uma parte do site que requer o login do usuário.
Como outros já disseram, ele irá bloquear seu navegador, então fique longe dele onde puder.
Em vez de chamadas síncronas, porém, geralmente os usuários desejam interromper um evento que está sendo carregado no momento e, em seguida, executar alguma outra operação. De certa forma, isso é sincronização, já que o primeiro evento é encerrado antes do segundo começar. Para fazer isso, use o método abort () no objeto de conexão xml.
fonte
Eu diria que, se você considerar o bloqueio do navegador do usuário enquanto a solicitação é concluída, é aceitável usar uma solicitação síncrona.
Se a serialização de solicitações for o seu objetivo, isso pode ser feito usando solicitações assíncronas, fazendo com que o retorno de chamada onComplete de sua solicitação anterior dispare o próximo na linha.
fonte
Existem muitos casos reais em que bloquear a IU é exatamente o comportamento desejado.
Pegue um aplicativo com vários campos e alguns campos devem ser validados por uma chamada xmlhttp para um servidor remoto fornecendo como entrada o valor deste campo e outros valores de campos.
No modo síncrono, a lógica é simples, o bloqueio experimentado pelo usuário é muito curto e sem problemas.
No modo assíncrono, o usuário pode alterar os valores de quaisquer outros campos enquanto o inicial está sendo validado. Essas mudanças irão acionar outras chamadas xmlhttp com valores do campo inicial ainda não validados. O que acontece se a validação inicial falhar? Pura bagunça. Se o modo de sincronização se tornar obsoleto e proibido, a lógica do aplicativo se tornará um pesadelo. Basicamente, o aplicativo deve ser reescrito para gerenciar bloqueios (por exemplo, desativar outros itens durante os processos de validação). A complexidade do código aumenta tremendamente. Não fazer isso pode levar à falha lógica e, em última instância, à corrupção de dados.
Basicamente, a questão é: o que é mais importante: experiência de interface do usuário não bloqueada ou risco de corrupção de dados? A resposta deve permanecer com o desenvolvedor do aplicativo, não com o W3C.
fonte
Eu posso ver um uso para solicitações XHR síncronas a serem usadas quando um recurso em uma localização variável deve ser carregado antes de outros recursos estáticos na página que dependem do primeiro recurso para funcionar totalmente. Na verdade, estou implementando essa solicitação XHR em um pequeno subprojeto meu, enquanto os recursos JavaScript residem em locais variáveis no servidor, dependendo de um conjunto de parâmetros específicos. Os recursos JavaScript subsequentes dependem desses recursos variáveis e DEVEM ser garantidos o carregamento desses arquivos antes que os outros arquivos dependentes sejam carregados, tornando assim o aplicativo inteiro.
Essa ideia base realmente se expande na resposta do vol7ron. Os procedimentos baseados em transações são realmente o único momento em que as solicitações síncronas devem ser feitas. Na maioria dos outros casos, as chamadas assíncronas são a melhor alternativa em que, após a chamada, o DOM é atualizado conforme necessário. Em muitos casos, como em sistemas baseados no usuário, você pode ter alguns recursos bloqueados para "usuários não autorizados" até que eles, por si só, estejam logados. Esses recursos, após a chamada assíncrona, são desbloqueados por meio de um procedimento de atualização de DOM.
Eu teria que finalmente dizer que concordo com os pontos da maioria das pessoas sobre o assunto: sempre que possível, as solicitações XHR síncronas devem ser evitadas, pois, da maneira como funciona, o navegador trava com chamadas síncronas. Ao implementar solicitações síncronas, elas devem ser feitas de uma maneira em que o navegador normalmente estaria bloqueado, digamos na seção HEAD antes que o carregamento da página realmente ocorra.
fonte
A partir de 2015, os aplicativos javascript para desktop estão se tornando mais populares. Normalmente, nesses aplicativos, ao carregar arquivos locais (e carregá-los usando XHR é uma opção perfeitamente válida), a velocidade de carregamento é tão rápida que não adianta complicar o código com async. É claro que pode haver casos em que assíncrono é o caminho a percorrer (solicitar conteúdo da Internet, carregar arquivos muito grandes ou um grande número de arquivos em um único lote), mas por outro lado, a sincronização funciona bem (e é muito mais fácil de usar) .
fonte
O jQuery usa AJAX síncrono internamente em algumas circunstâncias. Ao inserir HTML que contém scripts, o navegador não os executará. Os scripts precisam ser executados manualmente. Esses scripts podem anexar manipuladores de clique. Suponha que um usuário clique em um elemento antes que o manipulador seja anexado e a página não funcione conforme o esperado. Portanto, para evitar condições de corrida, o AJAX síncrono seria usado para buscar esses scripts. Como o AJAX síncrono bloqueia todo o resto, pode-se garantir que os scripts e eventos sejam executados na ordem certa.
fonte
O que acontece se você fizer uma chamada síncrona no código de produção?
O céu cai.
Não, sério, o usuário não gosta de um navegador travado.
fonte
Eu o utilizo para validar um nome de usuário, durante a verificação de que o nome de usuário ainda não existe.
Eu sei que seria melhor fazer isso de forma assíncrona, mas então eu deveria usar um código diferente para esta regra de validação específica. Eu explico melhor. Minha configuração de validação usa algumas funções de validação, que retornam verdadeiro ou falso, dependendo se os dados são válidos.
Como a função deve retornar, não posso usar técnicas assíncronas, então apenas faço isso síncrono e espero que o servidor responda prontamente o suficiente para não ser muito perceptível. Se eu usasse um retorno de chamada AJAX, teria que lidar com o resto da execução de forma diferente dos outros métodos de validação.
fonte
false
) e apenas defini-lo como verdadeiro ou falso quando o servidor responder. onchange do campo você resetar o flag e chamar o servidor novamente.Às vezes você tem uma ação que depende de outras pessoas. Por exemplo, a ação B só pode ser iniciada se A estiver concluída. A abordagem síncrona geralmente é usada para evitar condições de corrida . Às vezes, usar uma chamada síncrona é uma implementação mais simples do que criar uma lógica complexa para verificar cada estado de suas chamadas assíncronas que dependem umas das outras.
O problema com essa abordagem é que você "bloqueia" o navegador do usuário até que a ação seja concluída (até que a solicitação retorne, termine, carregue etc.). Portanto, tenha cuidado ao usá-lo.
fonte
Eu uso chamadas síncronas ao desenvolver código - tudo o que você fez enquanto a solicitação estava indo e voltando do servidor pode ocultar a causa de um erro.
Quando está funcionando, eu o torno assíncrono, mas tento incluir um timer de aborto e callbacks de falha, porque nunca se sabe ...
fonte
Razão:
Digamos que você tenha um aplicativo ajax que precisa fazer meia dúzia de get http para carregar vários dados do servidor antes que o usuário possa fazer qualquer interação.
Obviamente, você deseja que isso seja acionado no carregamento.
As chamadas síncronas funcionam muito bem para isso, sem nenhuma complexidade adicional ao código. É simples e direto.
Recua:
A única desvantagem é que o navegador bloqueia até que todos os dados sejam carregados ou até que ocorra um tempo limite. Quanto ao aplicativo ajax em questão, isso não é um grande problema porque o aplicativo não tem uso até que todos os dados iniciais sejam carregados de qualquer maneira.
Alternativo?
No entanto, muitos navegadores bloqueiam todas as janelas / guias quando o javascript está ocupado em qualquer uma delas, o que é um problema estúpido de design de navegador - mas, como resultado, o bloqueio em redes possivelmente lentas não é educado se impedir os usuários de usar outras guias enquanto aguarda o carregamento da página ajax.
No entanto, parece que as obtenções síncronas foram removidas ou restringidas dos navegadores recentes de qualquer maneira. Não tenho certeza se é porque alguém decidiu que sempre foram ruins, ou se os escritores de navegadores ficaram confusos com o WC Working Draft sobre o assunto.
http://www.w3.org/TR/2012/WD-XMLHttpRequest-20120117/#the-open-method faz parecer (consulte a seção 4.7.3) que você não tem permissão para definir um tempo limite ao usar o modo de bloqueio . Parece contra-intuitivo para mim: sempre que alguém bloqueia IO, é educado definir um tempo limite razoável, então por que permitir o bloqueio de IO, mas não com um tempo limite especificado pelo usuário?
Minha opinião é que o bloqueio de IO tem um papel vital em algumas situações, mas deve ser implementado corretamente. Embora não seja aceitável que uma guia ou janela do navegador bloqueie todas as outras guias ou janelas, isso é uma falha de design do navegador. Vergonha onde a vergonha é devida. Mas é perfeitamente aceitável em alguns casos que uma guia ou janela individual não responda por alguns segundos (ou seja, usando bloqueio IO / HTTP GET) em algumas situações - por exemplo, no carregamento da página, talvez muitos dados precisa ser antes que qualquer coisa possa ser feita. Às vezes, o código de bloqueio implementado corretamente é a maneira mais limpa de fazer isso.
É claro que uma função equivalente neste caso pode ser obtida usando get http assíncrono, mas que tipo de rotina idiota é necessária?
Acho que tentaria algo assim:
No carregamento do documento, faça o seguinte: 1: Configure 6 variáveis de sinalização globais "Concluído", inicializadas com 0. 2: Execute todos os 6 resultados de segundo plano (assumindo que a ordem não importa)
Em seguida, os retornos de chamada de conclusão para cada um dos 6 http gets definiriam seus respectivos sinalizadores "Concluído". Além disso, cada retorno de chamada verificaria todos os outros sinalizadores concluídos para ver se todos os 6 get HTTP foram concluídos. O último retorno de chamada a ser concluído, ao ver que todos os outros foram concluídos, chamaria a função REAL init que configuraria tudo, agora que os dados foram todos buscados.
Se a ordem de busca fosse importante - ou se o servidor da web não pudesse aceitar várias solicitações ao mesmo tempo - você precisaria de algo como isto:
Em onload (), o primeiro http get seria lançado. Em seu retorno de chamada, o segundo seria iniciado. Em seu retorno de chamada, o terceiro - e assim por diante e assim por diante, com cada retorno de chamada iniciando o próximo HTTP GET. Quando o último retornasse, ele chamaria a rotina init () real.
fonte
SYNC vs ASYNC: Qual é a diferença?
Basicamente, tudo se resume a isso:
Quando
doSomething
é síncrono, isso imprimiria:Em contraste, se
doSomething
for assíncrono , isso imprimiria:Como a função
doSomething
está realizando seu trabalho de forma assíncrona, ela retorna antes que o trabalho seja concluído. Portanto, só obtemos o resultado após a impressãoGoodbye cruel world!
Se dependermos do resultado de uma chamada assincrônica, precisamos colocar o código correspondente no retorno de chamada:
Como tal, apenas o fato de que 2 ou três coisas precisam acontecer em ordem não é razão para fazê-las de forma síncrona (embora o código de sincronização seja mais fácil para a maioria das pessoas trabalhar).
POR QUE USAR SÍNCRONO XMLHTTPREQUEST?
Existem algumas situações em que você precisa do resultado antes que a função chamada seja concluída. Considere este cenário:
Suponha que não tenhamos controle sobre o código de chamada (a
console.info
linha) e precisemos alterar a funçãolives
para perguntar ao servidor ... Não há como fazer uma solicitação assíncrona para o servidor de dentrolives
e ainda ter nossa resposta antes de serlives
concluída. Então não saberíamos se devíamos voltartrue
oufalse
. A única maneira de obter o resultado antes que a função seja concluída é fazendo uma solicitação síncrona.Como
Sami Samhuri
menciona em sua resposta, um cenário muito real em que você pode precisar de uma resposta à solicitação do servidor antes que sua função seja encerrada é oonbeforeunload
evento, já que é a última função do seu aplicativo que será executada antes de a janela ser fechada.NÃO PRECISO DE CHAMADAS DE SYNCH, MAS EU AS USO DE QUALQUER MANEIRA QUE SÃO MAIS FÁCEIS
Por favor, não. As chamadas síncronas bloqueiam seu navegador e fazem com que o aplicativo pare de responder. Mas você está certo. O código assíncrono é mais difícil. No entanto, existe uma maneira de tornar muito mais fácil lidar com isso. Não é tão fácil quanto sincronizar o código, mas está chegando perto: Promise s.
Aqui está um exemplo: Duas chamadas assincrônicas devem ser concluídas com sucesso antes que um terceiro segmento de código possa ser executado:
Aqui está como você implementaria
bookHotel
:Consulte também: Escreva melhor JavaScript com promessas .
fonte
XMLHttpRequest
é tradicionalmente usado para solicitações assíncronas. Às vezes (para depuração ou lógica de negócios específica), você deseja alterar todas / várias chamadas assíncronas em uma página para sincronizar.Você gostaria de fazer isso sem alterar tudo em seu código JS. O sinalizador async / sync oferece essa capacidade e, se projetado corretamente, você só precisa alterar uma linha em seu código / alterar o valor de um
var
durante o tempo de execução.fonte
O Firefox (e provavelmente todos os navegadores não IE) não oferece suporte a timeOut XHR assíncrono.
WebWorkers HTML5 suportam tempos limite. Portanto, você pode querer agrupar a solicitação de sincronização XHR para WebWorker com tempo limite para implementar XHR assíncrono com comportamento de tempo limite.
fonte
Acabei de passar por uma situação em que as solicitações assíncronas de uma lista de urls chamadas em sucessão usando forEach (e um loop for) faria com que as solicitações restantes fossem canceladas. Mudei para síncrono e eles funcionam conforme o planejado.
fonte
Usar solicitações HTTP síncronas é uma prática comum no negócio de publicidade móvel.
As empresas (também conhecidas como "Editores") que criam aplicativos geralmente veiculam anúncios para gerar receita. Para isso, eles instalam SDKs de publicidade em seu aplicativo. Muitos existem (MoPub, Ogury, TapJob, AppNext, Google Ads AdMob).
Esses SDKs veicularão anúncios em uma visualização da web.
Ao exibir um anúncio a um usuário, deve ser uma experiência tranquila , especialmente durante a reprodução de um vídeo. Não deve haver buffer ou carregamento em nenhum momento.
Para resolver isso
precaching
é usado. Onde a mídia (imagem / vídeos / etc) é carregada de forma síncrona no plano de fundo do webview.Por que não fazer isso de forma assíncrona?
onload
evento para saber quando o anúncio está "pronto" para ser veiculado ao usuárioCom a descontinuação de XMLHttpRequests síncronos , o negócio de anúncios provavelmente será forçado a mudar o padrão no futuro, a menos que outra maneira possa ser determinada.
fonte
O XHR síncrono pode ser muito útil para o desenvolvimento de ferramentas e / ou frameworks internos (de não produção). Imagine, por exemplo, que você deseja carregar uma biblioteca de código de forma síncrona no primeiro acesso, assim:
Antes de ficar confuso e cegamente regurgitar o mal da avaliação, tenha em mente que isso é apenas para testes locais. Para compilações de produção, _draw já estaria definido.
Portanto, seu código pode ser assim:
Este é apenas um exemplo de algo que seria impossível fazer sem sincronizar XHR. Você poderia carregar esta biblioteca antecipadamente, sim, ou fazer uma promessa / retorno de chamada, mas você não poderia carregar a lib de forma síncrona sem sincronizar o XHR. Pense em quanto esse tipo de coisa pode limpar seu código ...
Os limites do que você pode fazer com isso para ferramentas e estruturas (executando localmente) são limitados apenas pela sua imaginação. Porém, parece que a imaginação é um pouco limitada no mundo do JavaScript.
fonte
Bem, aqui está uma boa razão. Eu queria fazer uma solicitação http e, dependendo do resultado, chame click () em um tipo de entrada = arquivo. Isso não é possível com xhr ou fetch assíncrono. O retorno de chamada perde o contexto "ação do usuário", então o clique de chamada () é ignorado. O xhr síncrono salvou meu bacon.
fonte