A resposta é
Você pode usar promessas com getScript()
e aguardar até que todos os scripts sejam carregados, algo como:
$.when(
$.getScript( "/mypath/myscript1.js" ),
$.getScript( "/mypath/myscript2.js" ),
$.getScript( "/mypath/myscript3.js" ),
$.Deferred(function( deferred ){
$( deferred.resolve );
})
).done(function(){
//place your code here, the scripts are all loaded
});
FIDDLE
OUTRO FIDDLE
No código acima, adicionar um adiado e resolvê-lo $()
é como colocar qualquer outra função dentro de uma chamada jQuery, como $(func)
é o mesmo que
$(function() { func(); });
ou seja, ele espera o DOM estar pronto, portanto, no exemplo acima, $.when
espera que todos os scripts sejam carregados e o DOM esteja pronto devido à $.Deferred
chamada que é resolvida no retorno de chamada pronto do DOM.
Para uso mais genérico, uma função útil
Uma função utilitária que aceita qualquer matriz de scripts pode ser criada assim:
$.getMultiScripts = function(arr, path) {
var _arr = $.map(arr, function(scr) {
return $.getScript( (path||"") + scr );
});
_arr.push($.Deferred(function( deferred ){
$( deferred.resolve );
}));
return $.when.apply($, _arr);
}
que pode ser usado assim
var script_arr = [
'myscript1.js',
'myscript2.js',
'myscript3.js'
];
$.getMultiScripts(script_arr, '/mypath/').done(function() {
// all scripts loaded
});
onde o caminho será anexado a todos os scripts e também é opcional, o que significa que, se a matriz contiver o URL completo, também será possível fazer isso e deixar o caminho todo junto
$.getMultiScripts(script_arr).done(function() { ...
Argumentos, erros etc.
Como um aparte, observe que o done
retorno de chamada conterá vários argumentos correspondentes aos scripts passados, cada argumento representando uma matriz que contém a resposta
$.getMultiScripts(script_arr).done(function(response1, response2, response3) { ...
onde cada matriz conterá algo como [content_of_file_loaded, status, xhr_object]
. Geralmente, não precisamos acessar esses argumentos, pois os scripts serão carregados automaticamente de qualquer maneira, e na maioria das vezes o done
retorno de chamada é tudo o que realmente precisamos saber para saber que todos os scripts foram carregados, estou apenas adicionando-o para completar e nas raras ocasiões em que o texto real do arquivo carregado precisa ser acessado ou quando é necessário acessar cada objeto XHR ou algo semelhante.
Além disso, se algum dos scripts falhar ao carregar, o manipulador de falhas será chamado e os scripts subsequentes não serão carregados
$.getMultiScripts(script_arr).done(function() {
// all done
}).fail(function(error) {
// one or more scripts failed to load
}).always(function() {
// always called, both on success and error
});
$.Deferred(function( deferred ){$( deferred.resolve );})
aqui?$.ajaxSetup({ cache: true });
mas isso também pode afetar outras chamadas ajax que você não deseja armazenar em cache, há muito mais sobre isso nos documentos para getScript e ainda há um pequeno tutorial sobre como criar uma função getScript em cache chamada cachedScript.$.when($.getScript(scriptSrc_1), $.getScript(scriptSrc_2), $.getScript(scriptSrc_3), $.getScript(scriptSrc_4), $.Deferred(function(deferred) { $(deferred.resolve); })).done(function() { ... })
Eu implementei uma função simples para carregar vários scripts em paralelo:
Função
Uso
fonte
Carregue o seguinte script necessário no retorno de chamada do anterior, como:
fonte
Às vezes, é necessário carregar scripts em uma ordem específica. Por exemplo, o jQuery deve ser carregado antes da interface do usuário do jQuery. A maioria dos exemplos desta página carrega scripts em paralelo (assincronamente), o que significa que a ordem de execução não é garantida. Sem pedidos, o script
y
que dependex
pode ser interrompido se ambos forem carregados com êxito, mas na ordem errada.Proponho uma abordagem híbrida que permite o carregamento seqüencial de scripts dependentes + carregamento paralelo opcional + objetos adiados :
Os scripts nas duas filas serão baixados em paralelo; no entanto, os scripts em cada fila serão baixados em sequência, garantindo a execução ordenada. Gráfico em cascata:
fonte
Use yepnope.js ou Modernizr (que inclui yepnope.js como
Modernizr.load
).ATUALIZAR
Apenas para acompanhar, aqui está um bom equivalente ao que você tem atualmente usando o yepnope, mostrando dependências em vários scripts:
fonte
yepnope.injectJs( scriptSource )
no início do meu arquivo javascript, como incluir<script>
tags no arquivo html?$.getScript
. Este é um grande negócio.Encontrei vários problemas com o carregamento de vários scripts, incluindo um (pelo menos no Chrome) o mesmo domínio de carregamento a quente de scripts que não estavam em execução após serem carregados com sucesso pelo Ajax, onde o Cross Domain funciona perfeitamente! :(
A resposta selecionada para a pergunta original não funciona de maneira confiável.
Depois de muitas iterações, aqui está minha resposta final ao getScript (s) e ao carregar múltiplos scripts de forma assíncrona em uma ordem estrita específica com a opção de retorno de chamada carregada por script e retorno de chamada geral após a conclusão, Testado no jQuery 2.1+ e nas versões modernas do Chrome, Firefox e o Internet Explorer abandonado.
Meu caso de teste estava carregando arquivos para uma renderização THREE.JS webGL e iniciando o script de renderização quando THREE global ficou disponível usando uma verificação de intervalo passada para uma chamada de função anônima para onComplete.
A função Prototype (getScripts)
Como usar
A função é a que encontrei, usando Adiado (Preterido agora?), Quando, Sucesso e Concluído em minhas tentativas para NÃO ser 100% confiável! ?, Portanto, esta função e o uso do statusCode, por exemplo.
Você pode querer adicionar um comportamento de manipulação de erro / falha, se desejar.
fonte
Você pode fazer uso do
$.when
método, tentando a seguinte função:Esta função seria usada assim:
Essa é a maneira de usar o Promises e ter um mínimo de sobrecarga.
fonte
Ótima resposta, adeneo.
Demorei um pouco para descobrir como tornar sua resposta mais genérica (para que eu pudesse carregar uma matriz de scripts definidos por código). O retorno de chamada é chamado quando todos os scripts são carregados e executados. Aqui está a minha solução:
fonte
Anexar scripts com async = false
Aqui está uma abordagem diferente, mas super simples. Para carregar vários scripts, você pode simplesmente anexá-los ao corpo.
Mais informações aqui: https://www.html5rocks.com/en/tutorials/speed/script-loading/
fonte
O que você está procurando é um carregador compatível com AMD (como require.js).
http://requirejs.org/
http://requirejs.org/docs/whyamd.html
Existem muitos bons de código aberto, se você procurar. Basicamente, isso permite que você defina um módulo de código e, se depender de outros módulos de código, aguardará até o término do download desses módulos antes de continuar a execução. Dessa forma, você pode carregar 10 módulos de forma assíncrona e não deve haver problemas, mesmo que um dependa de alguns dos outros para execução.
fonte
Esta função garantirá que um arquivo seja carregado após o carregamento completo do arquivo de dependência. Você só precisa fornecer os arquivos em uma sequência, tendo em mente as dependências de outros arquivos.
fonte
Isso funciona para mim:
E use-o:
fonte
Aqui está a resposta usando a de Maciej Sawicki e implementando
Promise
como retorno de chamada:Usar:
Todos os arquivos Javascript são baixados o mais rápido possível e executados na ordem especificada. Então
taskNeedingParameters
é chamado.fonte
Versão mais curta da resposta abrangente de Andrew Marc Newton acima. Este não verifica o código de status para obter êxito, o que você deve fazer para evitar um comportamento indefinido da interface do usuário.
Este era para um sistema irritante, onde eu poderia garantir o jQuery, mas nenhum outro inclui, então eu queria uma técnica curta o suficiente para não ser criada em um script externo, se forçada a fazê-lo. (Você pode torná-lo ainda mais curto passando o índice 0 para a primeira chamada "recursiva", mas a força dos hábitos de estilo me fez adicionar o açúcar).
Também estou atribuindo a lista de dependências a um nome de módulo, para que esse bloco possa ser incluído em qualquer lugar em que você precise de "module1" e os scripts e a inicialização dependente serão incluídos / executados apenas uma vez (você pode efetuar login
index
na chamada de retorno e ver uma única ordem conjunto de solicitações AJAX em execução)fonte
Existe um plugin que estende o método getScript do jQuery. Permite carregamento assíncrono e síncrono e usa o mecanismo de cache do jQuery. Divulgação completa, eu escrevi isso. Sinta-se à vontade para contribuir se você encontrar um método melhor.
https://github.com/hudsonfoo/jquery-getscripts
fonte
Carrega n scripts um por um (útil se, por exemplo, o segundo arquivo precisar do primeiro):
fonte
com base na resposta de @adeneo acima: Combinando o carregamento de arquivos css e js
alguma sugestão de melhorias?
fonte
Você pode tentar usar a recursão. Isso fará o download deles em sincronia, um após o outro, até que o download completo da lista seja concluído.
fonte