Prefacio
ImagePool es una herramienta JS para administrar la carga de imágenes. ImagePool puede controlar el número de cargas de imagen concurrentes.
Para la carga de imágenes, la forma más primitiva es escribir una etiqueta IMG directamente, como: <img src = "image url" />.
Después de la optimización continua, ha aparecido un esquema de carga de retraso de imagen. Esta vez, la URL de la imagen no se escribe directamente en el atributo SRC, sino en un cierto atributo, como: <img src = "" data-src = "url de imagen" />. De esta manera, el navegador no cargará automáticamente la imagen. Cuando se necesita el momento apropiado, use JS para colocar la URL en el atributo de datos de datos SRC en el atributo SRC de la etiqueta IMG, o después de leer la URL, use JS para cargar la imagen y configure el atributo SRC después de cargar, y muestre la imagen.
Esto parece estar bien controlado, pero aún habrá problemas.
Aunque solo puede cargar una parte de la imagen, esta parte de la imagen aún puede ser un orden de magnitud relativamente grande.
Esto no es un gran problema para el lado de la PC, pero para el lado móvil, se cargan demasiadas imágenes concurrentes, lo que es muy probable que cause bloqueos de aplicaciones.
Por lo tanto, necesitamos urgentemente un mecanismo de almacenamiento de imágenes para controlar la concurrencia de carga de imágenes. Similar al grupo de conexión de la base de datos de backend, no crea demasiadas conexiones y puede reutilizar completamente cada conexión.
En este punto, nació ImagePool.
Mal diagrama esquemático
Instrucciones de uso
Primero, inicialice el grupo de conexión:
var ImagePool = initiMagePool (5);
InitIMagePool es un método global que se puede usar directamente en cualquier lugar. La función es crear un grupo de conexión, y puede especificar el número máximo de conexiones al grupo de conexión, opcionalmente, el valor predeterminado es 5.
En la misma página, múltiples llamadas a InitiMagePool devuelven la misma instancia central, que siempre es la primera, con una sensación de singleton. Por ejemplo:
La copia del código es la siguiente:
var ImagePool1 = initiMagePool (3);
var ImagePool2 = initiMagePool (7);
En este momento, el número máximo de conexiones entre ImagePool1 y ImagePool2 es 3, y la misma instancia central se usa internamente. Tenga en cuenta que el núcleo interno es el mismo, no que ImagePool1 === ImagePool2.
Después de la inicialización, puede cargar la imagen con confianza.
La forma más fácil de llamar es la siguiente:
La copia del código es la siguiente:
var ImagePool = initiMagePool (10);
ImagePool.Load ("URL de imagen", {
éxito: function (src) {
console.log ("éxito :::::"+src);
},
Error: función (src) {
console.log ("Error ::::"+Src);
}
});
Simplemente llame al método de carga en la instancia.
El método de carga tiene dos parámetros. El primer parámetro es la URL de la imagen que debe cargarse, y el segundo parámetro son varias opciones, incluidas las devoluciones de llamada exitosas y fallidas. La URL de la imagen se pasará durante las devoluciones de llamada.
De esta manera, solo puede pasar en una imagen, por lo que también se puede escribir en la siguiente forma:
La copia del código es la siguiente:
var ImagePool = initiMagePool (10);
ImagePool.Load (["Image 1Url", "Image 2URL"], {
éxito: function (src) {
console.log ("éxito :::::"+src);
},
Error: función (src) {
console.log ("Error ::::"+Src);
}
});
Al pasar en una matriz de URL de imagen, puede pasar múltiples imágenes.
Cuando cada imagen se carga con éxito (o falló), se llamará al método de éxito (o error) y se pasará la URL de la imagen correspondiente.
Pero a veces no necesitamos devoluciones de llamada como esta con frecuencia. Pase en una matriz de URL de imagen. Cuando se procesan todas las imágenes en esta matriz, las devoluciones de llamada son suficientes.
Solo agregue una opción:
La copia del código es la siguiente:
var ImagePool = initiMagePool (10);
ImagePool.Load (["Image 1Url", "Image 2URL"], {
éxito: función (sarray, earray, count) {
console.log ("sarray ::::"+sarray);
console.log ("Earray ::::"+Earray);
console.log ("cuenta :::::"+recuento);
},
Error: función (src) {
console.log ("Error ::::"+Src);
},
Una vez: verdadero
});
Al agregar un atributo Once a la opción y configurarlo en True, solo puede lograr una devolución de llamada una vez.
Esta vez, el método de éxito debe llamarse de nuevo, y el método de error se ignora en este momento.
En este momento, el método de éxito de devolución de llamada ya no pasa en un parámetro de URL de imagen, sino que pasa en tres parámetros, a saber: matriz de URL exitosa, matriz de URL fallida y número total de imágenes procesadas.
Además, hay una manera de obtener el estado interno del grupo de conexión:
La copia del código es la siguiente:
var ImagePool = initiMagePool (10);
console.log (imagepool.info ());
Al llamar al método de información, puede obtener el estado interno del grupo de conexión a la hora actual, y la estructura de datos es la siguiente:
Object.task.Cuent Número de tareas que esperan procesar en el grupo de conexión
Object.thread.cuent el número máximo de conexiones al grupo de conexión
Object.thread. Número libre de conexiones gratuitas al grupo de conexión
Se recomienda no llamar a este método con frecuencia.
Finalmente, debe tenerse en cuenta que si la imagen no se carga, se intentará como máximo 3 veces. Si la imagen no se carga al final, se volverá a llamar al método de error. El número de intentos se puede modificar en el código fuente.
Finalmente, permítanme enfatizar que los lectores pueden empujar las imágenes al grupo de conexión tanto como sea posible, sin preocuparse por la concurrencia excesiva. ImagePool lo ayudará a cargar estas imágenes en un desastre.
Finalmente, debe tenerse en cuenta que ImagePool no reducirá teóricamente la velocidad de carga de la imagen, es solo una carga suave.
Código fuente
La copia del código es la siguiente:
(función (exportaciones) {
//Soltero
Var instancia = nulo;
var vacíafn = function () {};
// Configuración predeterminada inicial
var config_default = {
// El número de "hilos" en el grupo de hilos
Hilo: 5,
// El número de reintento no pudo cargar la imagen
// prueba dos veces, agregue el original, un total de 3 veces
"Prueba": 2
};
//herramienta
var _helpers = {
// establecer el atributo DOM
setattr: (function () {
var img = nueva imagen ();
// juzga si el navegador admite el conjunto de datos HTML5
if (img.dataset) {
Función de retorno (DOM, nombre, valor) {
dom.dataset [nombre] = valor;
valor de retorno;
};
}demás{
Función de retorno (DOM, nombre, valor) {
dom.SetAttribute ("Data-"+nombre, valor);
valor de retorno;
};
}
} ()),
// Obtener atributo DOM
getATTR: (function () {
var img = nueva imagen ();
// juzga si el navegador admite el conjunto de datos HTML5
if (img.dataset) {
Función de retorno (DOM, nombre) {
return dom.dataset [nombre];
};
}demás{
Función de retorno (DOM, nombre) {
return dom.getAttribute ("Data-"+nombre);
};
}
} ())
};
/**
* Método de construcción
* @param max número máximo de conexiones. Valor.
*/
función imagePool (max) {
// Número máximo de concurrencia
this.max = max || config_default.thread;
this.linkhead = nulo;
this.linkNode = null;
// Cargando piscina
// [{img: dom, libre: true, nodo: nodo}]
//nodo
// {src: "", Opciones: {éxito: "fn", error: "fn", una vez: true}, intente: 0}
this.pool = [];
}
/**
* Inicialización
*/
Imagepool.prototype.initpool = function () {
var i, img, obj, _s;
_s = esto;
para (i = 0; i <this.max; i ++) {
obj = {};
img = nueva imagen ();
_Helpers.setattr (img, "id", i);
img.onload = function () {
VAR ID, SRC;
//Llamar de vuelta
//_s.getnode(this).options.success.call(null, this.src);
_s.notice (_s.getNode (this), "éxito", this.src);
// Tareas de procesamiento
_S.Executelink (esto);
};
img.onerror = function (e) {
var nodo = _s.getNode (this);
// juzga el número de intentos
if (node.try <config_default.try) {
node.try = node.try + 1;
// Agregar al final de la lista de tareas nuevamente
_s.appendNode (_s.ceatenode (node.src, node.options, node.notice, node.group, node.try));
}demás{
// Error de devolución de llamada
//node.options.error.call(null, this.src);
_s.notice (nodo, "error", this.src);
}
// Tareas de procesamiento
_S.Executelink (esto);
};
obj.img = img;
obj.Free = verdadero;
this.pool.push (obj);
}
};
/**
* Encapsulación de devolución de llamada
* @param nodo nodo. Objeto.
* @Param Status Status. Cadena. Valor opcional: éxito | Error (fallido)
* @Param SRC Ruta de imagen. Cadena.
*/
Imagepool.prototype.notice = function (nodo, status, src) {
node.notice (estado, src);
};
/**
* Procesamiento de tareas de lista vinculada
* @param dom Image DOM Object. Objeto.
*/
Imagepool.prototype.executelink = function (dom) {
// discernir si hay nodos en la lista vinculada
if (this.linkhead) {
// Cargue la siguiente imagen
this.setsrc (dom, this.linkhead);
// Eliminar el encabezado del enlace
this.shiftNode ();
}demás{
// Establezca su propio estado en inactivo
this.status (dom, verdadero);
}
};
/**
* Get inactivo "hilo"
*/
ImagePool.prototype.getFree = function () {
Var longitud, i;
para (i = 0, longitud = this.pool.length; i <longitud; i ++) {
if (this.pool [i] .Free) {
devolver esto.pool [i];
}
}
regresar nulo;
};
/**
* Configuración de atributos SRC encapsulados
* Debido a que cambiar el atributo SRC es equivalente a cargar la imagen, encapsula la operación
* @param dom Image DOM Object. Objeto.
* @param nodo nodo. Objeto.
*/
ImagePool.prototype.setsrc = function (dom, nodo) {
// Establecer el "hilo" en la piscina para que no sea idle
this.status (dom, falso);
// nodo afiliado
this.setNode (DOM, nodo);
// Carga la imagen
dom.src = node.src;
};
/**
* Actualizar el estado de "hilo" en el grupo
* @param dom Image DOM Object. Objeto.
* @Param Status Status. Booleano. Valor opcional: verdadero (inactivo) | falso (no idle)
*/
ImagePool.prototype.status = function (dom, status) {
var id = _helpers.getattr (dom, "id");
this.pool [id] .Free = status;
// estado inactivo, borre el nodo asociado
if (status) {
this.pool [id] .node = null;
}
};
/**
* Actualizar el nodo asociado del "hilo" en el grupo
* @param dom Image DOM Object. Objeto.
* @param nodo nodo. Objeto.
*/
ImagePool.prototype.setNode = function (dom, nodo) {
var id = _helpers.getattr (dom, "id");
this.pool [id] .node = node;
devuelve this.pool [id] .node === nodo;
};
/**
* Obtenga el nodo asociado del "hilo" en la piscina
* @param dom Image DOM Object. Objeto.
*/
ImagePool.prototype.getNode = function (dom) {
var id = _helpers.getattr (dom, "id");
devuelve this.pool [id] .node;
};
/**
* Interfaz externa, cargar imágenes
* @param src puede ser una cadena SRC o una matriz de cadenas SRC.
* @Param Opciones Parámetros definidos por el usuario. Incluye: devolución de llamada de éxito, devolución de llamada de error, una vez.
*/
Imagepool.prototype.load = function (src, options) {
var srcs = [],
gratis = nulo,
longitud = 0,
i = 0,
// Solo inicializa la estrategia de devolución de llamada una vez
notar = (function () {
if (options.once) {
Función de retorno (estado, src) {
var g = this.group,
o = this.Options;
//Registro
g [estado] .push (src);
// discernir si todas las reorganizaciones han sido procesadas
if (g.success.length + g.error.length === g.count) {
//asincrónico
// De hecho, se ejecuta por separado como otra tarea para evitar que la función de devolución de llamada se ejecute demasiado tiempo y afecte la velocidad de carga de la imagen
setTimeOut (function () {
O.Success.call (NULL, G.Success, G.Error, G.Count);
}, 1);
}
};
}demás{
Función de retorno (estado, src) {
var o = this.options;
// devolución de llamada directa
setTimeOut (function () {
o [estado] .call (nulo, src);
}, 1);
};
}
} ()),
grupo = {
Conde: 0,
éxito: [],
error: []
},
nodo = nulo;
Opciones = Opciones || {};
options.success = options.success || vacíafn;
options.error = options.error || vacíafn;
srcs = srcs.concat (src);
// Establecer el número de elementos grupales
grupo.count = srcs.length;
// viajar por las imágenes que necesitan cargarse
para (i = 0, longitud = srcs.length; i <longitud; i ++) {
// Crear un nodo
nodo = this.createnode (srcs [i], opciones, aviso, grupo);
// juzga si el grupo de hilos es gratis
gratis = this.getFree ();
if (gratis) {
// Si tiene tiempo libre, cargue la imagen inmediatamente
this.setsrc (free.img, nodo);
}demás{
// sin inactivo, agregue la tarea a la lista vinculada
this.appendNode (nodo);
}
}
};
/**
* Obtener información de estado interna
* @returns {{}}
*/
Imagepool.prototype.info = function () {
Var info = {},
longitud = 0,
i = 0,
nodo = nulo;
//Hilo
info.thread = {};
// Número total de hilos
info.thread.count = this.pool.length;
// Número de hilos inactivos
info.thread.free = 0;
//Tarea
info.task = {};
// Número de tareas pendientes
info.task.count = 0;
// Obtenga el número de "hilos" gratuitos
para (i = 0, longitud = this.pool.length; i <longitud; i ++) {
if (this.pool [i] .Free) {
info.thread.free = info.thread.free + 1;
}
}
// Obtener el número de tareas (longitud de la cadena de tareas)
nodo = this.linkhead;
if (nodo) {
info.task.count = info.task.count + 1;
while (node.next) {
info.task.count = info.task.count + 1;
nodo = node.next;
}
}
Información de retorno;
};
/**
* Crear un nodo
* @Param SRC Ruta de imagen. Cadena.
* @Param Opciones Parámetros definidos por el usuario. Incluye: devolución de llamada de éxito, devolución de llamada de error, una vez.
* @param Aviso Estrategia de devolución de llamada. función.
* @Param Group Información del grupo. Objeto. {Count: 0, éxito: [], Error: []}
* @param TR número de errores de reintento. Valor. El valor predeterminado es 0.
* @returns {{}}
*/
ImagePool.Prototype.CreateNode = function (src, opciones, aviso, grupo, tr) {
var nodo = {};
node.src = src;
node.options = options;
node.notice = aviso;
node.group = grupo;
nodo.try = tr || 0;
nodo de retorno;
};
/**
* Agregar nodos al final de la lista de tareas
* @param nodo nodo. Objeto.
*/
Imagepool.prototype.appendNode = function (nodo) {
// juzga si la lista vinculada está vacía
if (! this.linkhead) {
this.linkhead = nodo;
this.linkNode = node;
}demás{
this.linknode.next = node;
this.linkNode = node;
}
};
/**
* Eliminar el encabezado del enlace
*/
ImagePool.prototype.shiftNode = function () {
// discernir si hay nodos en la lista vinculada
if (this.linkhead) {
// modificar el encabezado de la lista de enlaces
this.linkhead = this.linkhead.next || nulo;
}
};
/**
* Exportar interfaz externa
* @param max número máximo de conexiones. Valor.
* @returns {{load: function, info: function}}
*/
exports.initImagePool = function (max) {
if (! instancia) {
instancia = nueva ImagePool (Max);
instance.initpool ();
}
devolver {
/**
* Cargando fotos
*/
load: function () {
instance.load.apply (instancia, argumentos);
},
/**
* Información interna
* @returns {* | any | void}
*/
info: function () {
return instance.info.call (instancia);
}
};
};
}(este));
Lo anterior es un ejemplo de cómo usar este administrador de carga de imágenes front-end de JavaScript particularmente impresionante. ¿Has aprendido a usarlo?