Eu usei carregadores (loaders) JavaScript durante anos; ou era o carregador de Dojo, ou curl.js, ou mesmo usando jQuery como um carregador de JavaScript, que é extremamente útil para solicitar um conjunto de recursos e agir depois que concluiu o carregamento. Cada carregador de JavaScript é cheio de recursos, eficiente, e faz um trabalho maravilhoso de preencher a API Promise que não existia no navegador quando o carregador é criado. O que se segue não é esse tipo de carregador.
Este carregador super simples permite o carregamento de imagem, CSS e arquivos JavaScript, usando a API Promise, e dispara um retorno de sucesso ou fracasso. Esse pequeno “carregador” (eu nem deveria chamá-lo assim) não:
- fornece resultados de cache (embora isso seria fácil)
- proporciona um módulo/objeto de retorno
- faz chamadas AJAX (embora um preenchimento XHR-to-Promise esteja disponível, ou você pode usar fetch)
- …ou qualquer outra coisa avançada
Aqui está o pequeno “carregador” em toda a sua glória:
var load = (function() { // Função que retorna uma função: https://davidwalsh.name/javascript-functions function _load(tag) { return function(url) { // Esta promise será usada por Promise.all para determinar o sucesso ou fracasso return new Promise(function(resolve, reject) { var element = document.createElement(tag); var parent = 'body'; var attr = 'src'; // Importante sucesso e erro para a promise element.onload = function() { resolve(url); }; element.onerror = function() { reject(url); }; // Necessário definir atributos diferentes dependendo do tipo de tag switch(tag) { case 'script': element.async = true; break; case 'link': element.type = 'text/css'; element.rel = 'stylesheet'; attr = 'href'; parent = 'head'; } // Injetar no documento para lançar o carregamento element[attr] = url; document[parent].appendChild(element); }); }; } return { css: _load('link'), js: _load('script'), img: _load('img') } })(); // Uso: Carrega diferentes tipos de arquivo com um callback Promise.all([ load.js('lib/highlighter.js'), load.js('lib/main.js'), load.css('lib/highlighter.css'), load.img('images/logo.png') ]).then(function() { console.log('Everything has loaded!'); }).catch(function() { console.log('Oh no, epic failure!'); });
Um objeto load é criado com as funções js, css e img, que aceitam uma URL para carregar. Cada função retorna uma Promise e o evento onload ou onerror da tag do recurso aciona resolve ou reject para o promise. Promise.all recolhe os recursos a serem carregados e then dispara o carregamento bem-sucedido de todos os recursos e catch caso algum deles falhar.
Tenho que salientar que ele se destina a ser um carregador muito, muito simples; por favor, lembre-se dos comentários sobre como ele não tem os recursos avançados que os outros carregadores têm. Eu amo como a API Promise torna o gerenciamento assíncrono e de recursos de carregamento, assim como a API ServiceWorker e a API fetch. Faça um favor a si mesmo e confira essas APIs impressionantes!
***
David Walsh faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: https://davidwalsh.name/javascript-loader