javascript - barra de progreso jquery
¿Cargar indicadores de progreso para buscar? (8)
Dado que ninguna de las respuestas resuelve el problema.
Solo por el bien de la implementación, puede detectar la velocidad de carga con una pequeña porción inicial de tamaño conocido y el tiempo de carga se puede calcular con la longitud del contenido / velocidad de carga. Puedes usar este tiempo como estimación.
Estoy luchando por encontrar documentación o ejemplos de implementación de un indicador de progreso de carga usando fetch .
Esta es la única referencia que he encontrado hasta ahora , que dice:
Los eventos de progreso son una característica de alto nivel que no llegará en busca por el momento. Puede crear el suyo mirando el encabezado
Content-Length
y utilizando una secuencia de transferencia para monitorear los bytes recibidos.Esto significa que puede manejar explícitamente las respuestas sin una
Content-Length
diferente. Y, por supuesto, incluso siContent-Length
está allí, puede ser una mentira. Con las transmisiones puedes manejar estas mentiras como quieras.
¿Cómo escribiría "un flujo de transferencia para monitorear los bytes" enviados? Si hace algún tipo de diferencia, estoy tratando de hacer esto para impulsar las cargas de imágenes desde el navegador a Cloudinary .
NOTA
: No estoy interesado en la
biblioteca Cloudinary JS
, ya que depende de jQuery y mi aplicación no.
Solo estoy interesado en el procesamiento de flujo necesario para hacer esto con javascript nativo y el polyfill de
fetch
de Github.
La parte clave es ReadableStream ≪ obj_response .body≫.
Muestra:
let parse=_/*result*/=>{
console.log(_)
//...
return /*cont?*/_.value?true:false
}
fetch('''').
then(_=>( a/*!*/=_.body.getReader(), b/*!*/=z=>a.read().then(parse).then(_=>(_?b:z=>z)()), b() ))
Puede probar ejecutarlo en una página enorme, por ejemplo, https://html.spec.whatwg.org/ y https://html.spec.whatwg.org/print.pdf . CtrlShiftJ y carga el código.
(Probado en Chrome).
Las transmisiones están comenzando a llegar a la plataforma web ( https://jakearchibald.com/2016/streams-ftw/ ) pero aún es pronto.
Pronto podrá proporcionar una secuencia como el cuerpo de una solicitud, pero la pregunta abierta es si el consumo de esa secuencia se relaciona con los bytes cargados.
Las redirecciones particulares pueden provocar que los datos se retransmitan a la nueva ubicación, pero las transmisiones no pueden "reiniciarse". Podemos solucionar esto convirtiendo el cuerpo en una devolución de llamada que se puede llamar varias veces, pero debemos asegurarnos de que exponer el número de redireccionamientos no es una pérdida de seguridad, ya que sería la primera vez en la plataforma que JS podría Detecta eso.
Algunos se preguntan si incluso tiene sentido vincular el consumo de flujo a los bytes cargados.
Larga historia corta: esto aún no es posible, pero en el futuro esto será manejado ya sea por secuencias o algún tipo de devolución de llamada de nivel superior pasado a
fetch()
.
Mi solución es usar axios , que lo soporta bastante bien:
axios.request( {
method: "post",
url: "/aaa",
data: myData,
onUploadProgress: (p) => {
console.log(p);
//this.setState({
//fileprogress: p.loaded / p.total
//})
}
}).then (data => {
//this.setState({
//fileprogress: 1.0,
//})
})
Tengo un ejemplo para usar esto en reaccionar en github.
No creo que sea posible. El borrador dice:
actualmente carece [ en comparación con XHR ] cuando se trata de solicitar progresión
(respuesta anterior):
El primer ejemplo en el
https://fetch.spec.whatwg.org/#fetch-api
da una idea de cómo:
Si desea recibir los datos del cuerpo progresivamente:
function consume(reader) { var total = 0 return new Promise((resolve, reject) => { function pump() { reader.read().then(({done, value}) => { if (done) { resolve() return } total += value.byteLength log(`received ${value.byteLength} bytes (${total} bytes in total)`) pump() }).catch(reject) } pump() }) } fetch("/music/pk/altes-kamuffel.flac") .then(res => consume(res.body.getReader())) .then(() => log("consumed the entire body without keeping the whole thing in memory!")) .catch(e => log("something went wrong: " + e))
Además del uso del
antipatrón del constructor
Promise
, puede ver esa
response.body
es un flujo desde el que puede leer byte a byte utilizando un lector, y puede activar un evento o hacer lo que quiera (por ejemplo, registrar el progreso) para cada uno de ellos
Sin embargo, la especificación de Streams no parece estar bastante terminada, y no tengo idea de si esto ya funciona en alguna implementación de recuperación.
Una posible solución sería utilizar el
new Request()
constructor
new Request()
luego verificar
Boolean
atributo
Boolean
Request.bodyUsed
El
bodyUsed
atributobodyUsed
debe devolver verdadero si estádisturbed
, y falso de lo contrario.
para determinar si se
distributed
secuencia
Se dice que un objeto que implementa la mezcla del
Body
sedisturbed
si elbody
no es nulo y sedisturbed
sustream
.
Devuelve la
Promise
fetch()
desde dentro
.then()
encadenada a la llamada recursiva
.read()
de un
ReadableStream
cuando
Request.bodyUsed
es igual a
true
.
Tenga en cuenta que el enfoque no lee los bytes de
Request.body
ya que los bytes se transmiten al punto final.
Además, la carga podría completarse mucho antes de que cualquier respuesta se devuelva por completo al navegador.
const [input, progress, label] = [
document.querySelector("input")
, document.querySelector("progress")
, document.querySelector("label")
];
const url = "/path/to/server/";
input.onmousedown = () => {
label.innerHTML = "";
progress.value = "0"
};
input.onchange = (event) => {
const file = event.target.files[0];
const filename = file.name;
progress.max = file.size;
const request = new Request(url, {
method: "POST",
body: file,
cache: "no-store"
});
const upload = settings => fetch(settings);
const uploadProgress = new ReadableStream({
start(controller) {
console.log("starting upload, request.bodyUsed:", request.bodyUsed);
controller.enqueue(request.bodyUsed);
},
pull(controller) {
if (request.bodyUsed) {
controller.close();
}
controller.enqueue(request.bodyUsed);
console.log("pull, request.bodyUsed:", request.bodyUsed);
},
cancel(reason) {
console.log(reason);
}
});
const [fileUpload, reader] = [
upload(request)
.catch(e => {
reader.cancel();
throw e
})
, uploadProgress.getReader()
];
const processUploadRequest = ({value, done}) => {
if (value || done) {
console.log("upload complete, request.bodyUsed:", request.bodyUsed);
// set `progress.value` to `progress.max` here
// if not awaiting server response
// progress.value = progress.max;
return reader.closed.then(() => fileUpload);
}
console.log("upload progress:", value);
progress.value = +progress.value + 1;
return reader.read().then(result => processUploadRequest(result));
};
reader.read().then(({value, done}) => processUploadRequest({value,done}))
.then(response => response.text())
.then(text => {
console.log("response:", text);
progress.value = progress.max;
input.value = "";
})
.catch(err => console.log("upload error:", err));
}
const req = await fetch(''./foo.json'');
const total = Number(req.headers.get(''content-length''));
let loaded = 0;
for await(const {length} of req.body.getReader()) {
loaded = += length;
const progress = ((loaded / total) * 100).toFixed(2); // toFixed(2) means two digits after floating point
console.log(`${progress}%`); // or yourDiv.textContent = `${progress}%`;
}
const response = await fetch(url);
const total = Number(response.headers.get(''content-length''));
const reader = response.body.getReader();
let bytesReceived = 0;
while (true) {
const result = await reader.read();
if (result.done) {
console.log(''Fetch complete'');
break;
}
bytesReceived += result.value.length;
console.log(''Received'', bytesReceived, ''bytes of data so far'');
}
gracias a este enlace: https://jakearchibald.com/2016/streams-ftw/