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
doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
eles serão executados em ordem. doSomethingElse
não será iniciado até que doSomething
seja concluído. doSomethingUsefulThisTime
, por sua vez, não será iniciado até que doSomethingElse
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
doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
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
, e some_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
function some_3secs_function(value, callback){
//do stuff
callback();
}
então você pode ligar então em ordem, assim:
some_3secs_function(some_value, function() {
some_5secs_function(other_value, function() {
some_8secs_function(third_value, function() {
//All three functions have completed, in order.
});
});
});
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ção
setTimeout(doSomething, 10);
setTimeout(doSomethingElse, 10);
setTimeout(doSomethingUsefulThisTime, 10);
Isso é, 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.
function executeAsynchronously(functions, timeout) {
for(var i = 0; i < functions.length; i++) {
setTimeout(functions[i], timeout);
}
}
Isso pode ser chamado assim:
executeAsynchronously(
[doSomething, doSomethingElse, doSomethingUsefulThisTime], 10);
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.