Se eu precisar chamar essas funções uma após a outra,
$('#art1').animate({'width':'1000px'},1000);
$('#art2').animate({'width':'1000px'},1000);
$('#art3').animate({'width':'1000px'},1000);
Eu sei no jQuery que eu poderia fazer algo como:
$('#art1').animate({'width':'1000px'},1000,'linear',function(){
$('#art2').animate({'width':'1000px'},1000,'linear',function(){
$('#art3').animate({'width':'1000px'},1000);
});
});
Mas, vamos supor que eu não estou usando jQuery e desejo chamar:
some_3secs_function(some_value);
some_5secs_function(some_value);
some_8secs_function(some_value);
Como devo chamar essas funções para executar some_3secs_function
e APÓS a chamada terminar, depois executar some_5secs_function
e APÓS a chamada terminar, e depois ligar some_8secs_function
?
ATUALIZAR:
Isso ainda não está funcionando:
(function(callback){
$('#art1').animate({'width':'1000px'},1000);
callback();
})((function(callback2){
$('#art2').animate({'width':'1000px'},1000);
callback2();
})(function(){
$('#art3').animate({'width':'1000px'},1000);
}));
Três animações começam ao mesmo tempo
Onde está meu erro?
Respostas:
Em Javascript, existem funções síncronas e assíncronas .
Funções síncronas
A maioria das funções em Javascript é síncrona. Se você chamar várias funções síncronas seguidas
eles serão executados em ordem.
doSomethingElse
não será iniciado até quedoSomething
seja concluído.doSomethingUsefulThisTime
, por sua vez, não será iniciado até quedoSomethingElse
seja concluído.Funções assíncronas
A função assíncrona, no entanto, não espera um pelo outro. Vejamos o mesmo exemplo de código que tivemos acima, desta vez assumindo que as funções são assíncronas
As funções serão inicializadas em ordem, mas todas serão executadas aproximadamente ao mesmo tempo. Você não pode prever consistentemente qual terminará primeiro: aquele que levar o menor tempo para executar terminará primeiro.
Mas, às vezes, você deseja que funções assíncronas sejam executadas em ordem e, às vezes, que funções síncronas sejam executadas de forma assíncrona. Felizmente, isso é possível com retornos de chamada e tempos limite, respectivamente.
Retornos de chamada
Vamos supor que temos três funções assíncronas que queremos executar em ordem,
some_3secs_function
,some_5secs_function
, esome_8secs_function
.Como as funções podem ser passadas como argumentos em Javascript, você pode passar uma função como retorno de chamada para executar após a conclusão da função.
Se criarmos funções como esta
então você pode ligar então em ordem, assim:
Timeouts
Em Javascript, você pode dizer a uma função para executar após um certo tempo limite (em milissegundos). Com efeito, isso pode fazer com que as funções síncronas se comportem de forma assíncrona.
Se tivermos três funções síncronas, podemos executá-las de forma assíncrona usando a
setTimeout
funçãoIsso é, no entanto, um pouco feio e viola o princípio DRY [wikipedia] . Poderíamos limpar isso um pouco, criando uma função que aceite uma matriz de funções e um tempo limite.
Isso pode ser chamado assim:
Em resumo, se você possui funções assíncronas que deseja executar de forma síncrona, use retornos de chamada e se tiver funções síncronas que deseja executar de forma assíncrona, use tempos limite.
fonte
Esta resposta usa
promises
, um recurso JavaScript doECMAScript 6
padrão. Se sua plataforma de destino não suportarpromises
, preencha com o PromiseJs .Veja minha resposta aqui. Aguarde até que uma Função com animações termine até executar outra Função, se você quiser usar
jQuery
animações.Aqui está a aparência do seu código com
ES6 Promises
ejQuery animations
.Métodos normais também podem ser envolvidos
Promises
.O
then
método é executado assim quePromise
finalizado. Normalmente, o valor de retorno dofunction
passado parathen
é passado para o próximo como resultado.Mas se a
Promise
for retornado, a próximathen
função aguardará aPromise
execução concluída e receberá os resultados (o valor que é passado parafulfill
).fonte
Parece que você não está apreciando completamente a diferença entre a execução de funções síncronas e assíncronas .
O código que você forneceu na atualização executa imediatamente cada uma das funções de retorno de chamada, que, por sua vez, iniciam imediatamente uma animação. As animações, no entanto, são executadas assincronamente . Funciona assim:
setTimeout
com uma função que contém a próxima etapa da animação e um atrasosetTimeout
executaIsso continua até que a última etapa da animação seja concluída. Enquanto isso, suas funções síncronas foram concluídas há muito tempo. Em outras palavras, sua chamada para a
animate
função não leva realmente três segundos. O efeito é simulado com atrasos e retornos de chamada.O que você precisa é de uma fila . Internamente, o jQuery enfileira as animações, executando apenas o retorno de chamada quando a animação correspondente é concluída. Se o seu retorno de chamada iniciar outra animação, o efeito é que eles serão executados em sequência.
No caso mais simples, isso é equivalente ao seguinte:
Aqui está uma função de loop assíncrona geral. Ele chamará as funções fornecidas em ordem, aguardando o número especificado de segundos entre cada uma.
Uso:
Obviamente, você pode modificar isso para obter tempos de espera configuráveis ou para executar imediatamente a primeira função ou para interromper a execução quando uma função na cadeia retornar
false
ou paraapply
as funções em um contexto especificado ou o que mais você precisar.fonte
Acredito que a biblioteca assíncrona fornecerá uma maneira muito elegante de fazer isso. Embora promessas e retornos de chamada possam ser um pouco difíceis de conciliar, o assíncrono pode fornecer padrões simples para otimizar seu processo de pensamento. Para executar funções em série, você precisará colocá-las em uma cascata assíncrona . Na linguagem assíncrona, toda função é chamada a
task
que recebe alguns argumentos e acallback
; qual é a próxima função na sequência. A estrutura básica seria algo como:Eu apenas tentei explicar brevemente a estrutura aqui. Leia o guia em cascata para obter mais informações, é muito bem escrito.
fonte
suas funções devem ter uma função de retorno de chamada, que é chamada quando termina.
então o uso seria como:
fonte
Não vou entrar em uma discussão profunda sobre setTimeout aqui, mas:
fonte
Como você o marcou com javascript, eu usaria um controle de timer, já que seus nomes de função são 3, 5 e 8 segundos. Portanto, inicie o cronômetro, 3 segundos, ligue para o primeiro, 5 segundos para o segundo, 8 segundos para o terceiro e, quando terminar, pare o temporizador.
Normalmente, em Javascript, o que você tem é correto, pois as funções estão sendo executadas uma após a outra, mas, como parece que você está tentando fazer uma animação programada, um cronômetro seria sua melhor aposta.
fonte
fonte
next
faz?Você também pode usar promessas desta maneira:
Você precisaria se tornar
some_value
global para acessá-lo de dentro do .thenComo alternativa, a partir da função externa, você poderia retornar o valor que a função interna usaria, assim:
fonte
Eu uso uma função 'waitUntil' com base no setTimeout do javascript
Isso funcionaria perfeitamente se suas funções definissem uma determinada condição como verdadeira, que você seria capaz de pesquisar. Além disso, ele vem com tempos limites, que oferecem alternativas para o caso de sua função falhar em fazer alguma coisa (mesmo dentro do intervalo de tempo. Pense no feedback do usuário!)
por exemplo
fonte
Se o método 1 precisar ser executado após o método 2, 3, 4. O seguinte snippet de código pode ser a solução para isso usando o objeto Adiado em JavaScript.
fonte