Thats những gì đang xảy ra (giả):
Khi bạn đang gõ chậm:
.keyup1
.remove1
//asynchronous ajax1 request takes some time here...
.append1
.keyup2
.remove2
//asynchronous ajax2 request takes some time here...
.append2
Khi bạn gõ nhanh:
.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
Để giải quyết vấn đề bản sao , bạn sẽ muốn làm cho kết quả của bạn xóa/thêm hoạt động nguyên tử - sử dụng .replaceWith
.
kết quả xây dựng HTML khối đầu tiên là chuỗi và sau đó làm .replaceWith
thay vì .remove
/.append
:
var result = '';
for (i in results) {
result += "<div class='result'>" + results[i].name + "</div>";
}
$("#sresults").replaceWith('<div id="sresults">' + result + '</div>');
Một vấn đề khác (không liên quan đến bản sao) có thể là kết quả cũ ghi đè lên phiên bản mới hơn mà đến sớm (vì AJAX không đồng bộ và máy chủ có thể đưa ra các phản hồi không theo thứ tự nhận được yêu cầu).
Một cách tiếp cận để tránh điều này đánh dấu được gắn khứ hồi (loại "số sê-ri") cho mỗi yêu cầu, và kiểm tra nó trong phản ứng:
//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 ...
}
});
On phía máy chủ:
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);
}
Một cách tiếp cận sẽ là thực hiện .ajax()
yêu cầu đồng bộ, thiết lập tùy chọn async
tới false
. Tuy nhiên điều này có thể tạm khóa trình duyệt trong khi yêu cầu được kích hoạt (xem docs)
Và cũng chắc chắn bạn nên giới thiệu thời gian chờ như algiecas gợi ý để giảm tải trên máy chủ (đây là vấn đề thứ ba, không liên quan đến các bản sao cũng không yêu cầu/lệnh trả lời).
Tôi ha (ve) d cùng một vấn đề! +1 – genesis
Bạn không nên gọi .append() trong một vòng lặp. Tạo chuỗi và gọi .append() một lần, vì lý do hiệu suất. Mỗi khi bạn gọi .append(), trình phân tích cú pháp HTML phải hoạt động và trình duyệt phải vẽ lại một phần.Nó nhanh hơn để làm điều này một lần với một đoạn lớn hơn để làm điều này rất thường xuyên với khối nhỏ hơn. – ckruse
@ckruse thanx, tôi chuyển sang $ .each và vẫn còn cùng một vấn đề, mặc dù bây giờ tôi có thể gõ nhanh hơn một chút để không có nó ... :) – ilyo