Kỹ thuật xử lý hàng đợi khi gửi ajax
Nếu bạn cần xử lý ajax nhiều lần và thứ tự thực hiện giữa các lần gửi ajax thì bạn sẽ áp dụng kỹ thuật đệ quy ajax, hay còn gọi là thiết lập hàng đợi trong ajax. Đây là một kỹ thuật cũng nâng cao và nó chủ yếu là do kinh nghiệm của mỗi người nên trong bài này mình chỉ chia sẻ kinh nghiệm của mình, nếu có gì sai mong bạn bỏ qua.
Hàng đợi là gi? hàng đợi là một khái niệm mà bạn đã học rồi nên mình không nói nhiều về. Nó có nhiều loại nhưng mình đề cập đến một loại hàng đợi giống như khi bạn xếp hàng thanh toán tiền trong siêu thị vậy, nghĩa là bạn sẽ phải xếp hàng và đi theo thứ tự ai đến trước thì được thanh toán trước, khi nào người đó thanh toán xong thì người tiếp theo mới được thanh toán. Và kỹ thuật này áp dụng vào lập trình hoàn toàn được.
1. Tình huống bài toán hàng đợi
Để các bạn dễ hiểu hơn thì mình đưa ra một ví dụ thế này.
Mình sẽ xây dựng một ứng dụng gồm một ô textbox
và một button
như hình sau:
Bài viết này được đăng tại [free tuts .net]
Khi người dùng click vào nút Send
thì chương trình sẽ tạo ra một bảng gồm 10 phần tử (10 tasks) và trạng thái của các phần tử (Waitting, Sendding, Finished). Lúc này hệ thống bắt đầu xử lý từng task bằng ajax.
Nhìn thoáng qua thì nó không ứng dụng gì nhưng nếu bạn biết cách áp dụng vào bài toán của bạn thì nó sẽ có tác dụng ngay. Ví dụ bạn viết chương trình gửi email với số lượng lớn thì bạn sẽ phải gửi từng email, lúc này danh sách hàng đợi sẽ là tổng số email. Email nào chưa gửi thì ở trạng thái Waitting, email nào đang gửi thì ở trạng thái Sendding và email nào gửi rồi thì ở trạng thái Finished.
2. Xử lý ajax theo hàng đợi
Trước tiên bạn cần tạo hai file:
sleep.php
là file nhận request từ ajaxindex.html
là file chính
Cả hai file này cùng nằm trong một thư mục www
hoặc htdocs
của Webserver ảo nhé các bạn.
File sleep.php
:
Vì mình demo không có sử dụng database hay gửi email nên mình sẽ dùng hàm sleep
ngủ 2 giây để các bạn thấy trạng thái rõ ràng hơn. Lúc này nội dung của file như sau:
<?php sleep(2); ?>
File index.html
:
<!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="https://code.jquery.com/jquery-1.10.2.js"></script> <style> .red{ color: red; } .blue{ color:blue; } .pink{ color:pink; } </style> <script language="javascript"> $(document).ready(function() { // Code }); </script> </head> <body> <input type="text" id="num-thread" value="10"/> <input type="button" id="send-request" value="Send"/> <div id="results"></div> </body> </html>
Trong file này bạn cần chú ý các điểm sau:
- Mình khai báo 3
class
CSS để hiển thị màu sắc cho các trạng thái - Mình có khai báo một thẻ
script
dùng để code JS, nên sau này những đoạn code JS sẽ được đặt vào vị trí này - Có một thẻ
div#results
dùng để hiển thị bảng task
Bây giờ chạy file lên bạn sẽ có giao diện gồm một ô input và một button như hình trên. Bây giờ ta bắt đầu code Ajax cho nó nhé.
Mình sẽ tạo hai hàm như sau:
- Hàm
display_html(num)
dùng để hiển thị bảng danh sách các task như trên và tham số truyền vào là số lượng task (num
) - Hàm
send_ajax(num, index)
dùng để gửi ajax và tham số truyền vào gồm số lượng task (num
) và task cần gửi (index
)
Hàm display_html().
function display_html(num) { var html = ''; html += '<table border="1" cellpadding="5">'; html += '<tr>'; html += '<td>Num</td>'; html += '<td>Status</td>'; html += '</tr>'; for (var i = 0; i < num; i++){ html += '<tr>'; html += '<td>'+(i+1)+'</td>'; html += '<td id="waitting'+i+'" class="pink">Waitting...</td>'; html += '</tr>'; } html += '</table>' $('#results').html(html); }
Các bạn để ý mình có gán ID cho cột trạng thái với quy luật '<td id="waitting'+i+'" class="pink">Waitting...</td>'
. trong đó i là số thứ tự của tas, điều này quan trọng vì hàm send_ajax()
sẽ dựa vào id này để bik cần thay đổi trang thái cho task nào.
Hàm send_ajax().
function send_ajax(num, index) { // Kiểm tra xem task đã hết chưa, nếu hết thì dừng if (index > (num - 1)){ return false; } // Chuyển trang thái từ waitting san sendding $('#waitting'+index).removeClass('pink').addClass('red').html('Sending...'); // Gửi ajax $.ajax({ url : 'sleep.php', type : 'post', dataType : 'text', success : function() { // Sau khi thành công thì chuyển trạng thái sang finished $('#waitting'+index).removeClass('red').addClass('blue'); $('#waitting'+index).html('Finished'); } }) .always(function(){ // Xử lý task tiếp theo send_ajax(num, ++index); }); }
Ok vậy là ta đã có hai hàm, bây giờ ta sẽ viết javascript xử lý sự kiện click vào button như sau:
$('#send-request').click(function() { // Lấy số lượng task từ user nhập vào var num = parseInt($('#num-thread').val()); // Ẩn textbox và button $(this).remove(); $('#num-thread').remove(); // Hiển thị table danh sách task display_html(num); // gửi ajax cho lần đầu tiên (task = 1) send_ajax(num, 0); });
Ok và đây là toàn bộ file index.html.
<!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="https://code.jquery.com/jquery-1.10.2.js"></script> <style> .red{ color: red; } .blue{ color:blue; } .pink{ color:pink; } </style> <script language="javascript"> $(document).ready(function() { // Hàm hiển thị danh sách hàng task function display_html(num) { var html = ''; html += '<table border="1" cellpadding="5">'; html += '<tr>'; html += '<td>Num</td>'; html += '<td>Status</td>'; html += '</tr>'; for (var i = 0; i < num; i++){ html += '<tr>'; html += '<td>'+(i+1)+'</td>'; html += '<td id="waitting'+i+'" class="pink">Waitting...</td>'; html += '</tr>'; } html += '</table>' $('#results').html(html); } // Hàm gửi ajax function send_ajax(num, index) { // Kiểm tra xem task đã hết chưa, nếu hết thì dừng if (index > (num - 1)){ return false; } // Chuyển trang thái từ waitting san sendding $('#waitting'+index).removeClass('pink').addClass('red').html('Sending...'); // Gửi ajax $.ajax({ url : 'sleep.php', type : 'post', dataType : 'text', success : function() { // Sau khi thành công thì chuyển trạng thái sang finished $('#waitting'+index).removeClass('red').addClass('blue'); $('#waitting'+index).html('Finished'); } }) .always(function(){ // Xử lý task tiếp theo send_ajax(num, ++index); }); } // Khi click gửi request $('#send-request').click(function() { // Lấy số lượng task từ user nhập vào var num = parseInt($('#num-thread').val()); // Ẩn textbox và button $(this).remove(); $('#num-thread').remove(); // Hiển thị table danh sách task display_html(num); // gửi ajax cho lần đầu tiên (task = 1) send_ajax(num, 0); }); }); </script> </head> <body> <input type="text" id="num-thread" value="10"/> <input type="button" id="send-request" value="Send"/> <div id="results"></div> </body> </html>
3. Lời kết
Bạn hoàn toàn có thể cải tiến chương trình này bằng cách viết chương trình gửi email hàng loạt, trong đó:
- số lượng
task
ở ô input bạn sẽ cho người dùng nhập danh sách email và cách nhau bởi dấu phẩy - file
sleep.php
có nhiệm vụ nhận email và gửi - đoạn
javascript
có nhiệm vụ chuyển danh sách email và đưa vào hàng đợi, sau đó gửi từng email.
Vì mình cũng hơi bận nên chỉ đưa ra ý tưởng vậy thôi, chúc các bạn thành công!
Danh sách file tải về
Tên file tải về | Pass giải nén |
---|---|
Tải bài học định dạng PDF | freetuts.net hoặc gameportable.net |