eso es lo que está sucediendo (pseudocódigo):
Cuando se está escribiendo lenta:
.keyup1
.remove1
//asynchronous ajax1 request takes some time here...
.append1
.keyup2
.remove2
//asynchronous ajax2 request takes some time here...
.append2
Cuando se está escribiendo rápido:
.keyup1
.remove1
//asynchronous ajax1 request takes some time here...
//and keyup2 happens before ajax1 is complete
.keyup2
.remove2
.append1
//asynchronous ajax2 request takes some time here...
.append2
//two results were appended _in a row_ - therefore duplicates
Para resolver un problema duplicados , deseará hacer que sus resultados eliminen/añadan una operación atómica - usando .replaceWith
.
resultados se basan en bloque HTML primero como cadena y luego hacer la .replaceWith
en lugar de .remove
/.append
:
var result = '';
for (i in results) {
result += "<div class='result'>" + results[i].name + "</div>";
}
$("#sresults").replaceWith('<div id="sresults">' + result + '</div>');
Otro problema (no relacionado con duplicados) puede ser ese resultado mayores sobrescribe nuevo que llegó antes de (porque AJAX es asíncrono y el servidor puede emitir respuestas no en el mismo orden en que recibe las solicitudes).
Un enfoque para evitar este marcador es unir ida y vuelta (clase de "número de serie") a cada solicitud, y la comprobación de que en respuesta:
//this is global counter, you should initialize it on page load, global scope
//it contains latest request "serial number"
var latestRequestNumber = 0;
$.ajax({
type: "POST",
url: "<?= site_url('pages/ajax_search') ?>",
//now we're incrementing latestRequestNumber and sending it along with request
data: {company : serchval, requestNumber: ++latestRequestNumber},
success: function(data) {
var results = (JSON.parse(data));
//server should've put "serial number" from our request to the response (see PHP example below)
//if response is not latest (i.e. other requests were issued already) - drop it
if (results.requestNumber < latestRequestNumber) return;
// ... otherwise, display results from this response ...
}
});
En el lado del servidor:
function ajax_search() {
$response = array();
//... fill your response with searh results here ...
//and copy request "serial number" into it
$response['requestNumber'] = $_REQUEST['requestNumber'];
echo json_encode($response);
}
Otro El enfoque consistiría en hacer .ajax()
solicitudes sincrónicas, configurando la opción async
en false
. Sin embargo, esto puede bloquear temporalmente el navegador mientras solicitud está activa (ver docs)
Y también sin duda debe introducir el tiempo de espera como algiecas sugiere para reducir la carga en el servidor (este es el tercer problema, no relacionado con duplicados ni a la solicitud/orden de respuesta).
¡He (ve) d el mismo problema! +1 – genesis
No debe llamar a .append() en un bucle. Cree una cadena y llame a .append() una vez, por motivos de rendimiento. Cada vez que llamas a .append(), el analizador de HTML tiene que funcionar y el navegador tiene que hacer un redibujado de partición.Es más rápido hacer esto una vez con un gran trozo que hacer esto muy a menudo con trozos más pequeños. – ckruse
@ckruse thanx, cambié a $ .each y sigue teniendo el mismo problema, aunque ahora puedo escribir un poco más rápido para no tenerlo ... :) – ilyo