Xử lí bất đồng bộ

Chào mn, em đang làm 1 form gửi request = ajax. cơ chế kiểu:

  • người dùng nhập dữ liệu vào 1 textareaa, tách thành mảng bởi dấu xuống dòng \n. Ví dụ:
    a
    b
    c
    => được arrayZ [a,b,c]

  • dùng vòng lặp duyệt mảng này, ajax post element đầu tiên ( là a) lên 1 url để xử lí, url này lại trả về 1 arrayX .

  • duyệt tiếp arrayX vừa trả về. sau khi xử lí xong toàn bộ element trong arrayX này thì duyệt tiếp element tiếp theo của arrayZ mà người dùng nhập (là b) …

em có viết code như dưới, nhưng nó ra kq ko như mong đợi.

c => 1
b => 1
a => 1
c => 2
b => 2
a => 2
c => 3
b => 3
a => 3

code phía dưới em fix cứng hết giá trị người dùng nhập và data ajax trả về để test luôn ạ. mn click vào button “Click” là dc ah

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
    <style>
        #token{border:1px solid red;}
        #result{border:1px solid green;}
    </style>
</head>
<body>
    <textarea id="token" rows="5"></textarea>
    <br />
    <button id="click">
    Click
    </button>
    <br />
    <textarea id="result" rows="10" ></textarea>
    <br />
    <button id="done" style="display:none">Done</button>
    <script>
        $('#click').click(function(){
            var token = ['a', 'b', 'c'];
            $.each(token, function(index, item){
                $.ajax({
                    url: 'https://sv.hacklike.me/api/bot/service.php', //url test, dont care
                    method: 'POST',
                    data: {}
                }).done(function(result){
                    // var result = JSON.parse(result);
                    var result = [1,2,3]; //hard code test
                    $.each(result, function(_index, _item){
                        setTimeout(function(){
                            $('#result').append(item+ ' => '+ _item + "\n");
                        }, _index * 2000)
                    })
                })
            })
        });
    </script>
</body>
</html>

em muốn kết quả là
a => 1,
a => 2,
a => 3,
b => 1,
b => 2,
b => 3

(mỗi dòng show ra sau mỗi 2s)

trước giờ nếu code đơn giản thì em hay dùng async: false , nhưng dùng cái này cho nhiều ajax trong vòng lặp thì nó đơ luôn trình duyệt. em tìm thì thêm có nhiều cách , nhưng nhìn khá là khó hiểu, và đa số thấy là bảo sử dụng Promise , search cái này ở jquery thì ra .when() ,.promise(), .deferered() . Và còn có cả async, await. Nhiều thứ quá và em đọc chưa hiểu nên em không biết sử dụng cái nào, a/c nào có kn chỉ giáo cách chuẩn nhất với ạ.

Mình muốn hỏi là vì sao bạn lại làm như vậy? có trường hợp thực tế nào cần làm như vậy không?

mình đang cần mà.
ví dụ token thứ 1 => ajax get được 5000 bạn bè (mảng 5000 elem) => gửi từng id bạn bè đến 1 url khác để xử lí tiếp

=> xử lí tiếp token thứ 2 => get được 2000 bạn bè => gửi từng id bạn bè để xử lí tiếp

cần chạy lần lượt cách nhau 1 khoảng để không bị block, bạn có ý tưởng nào khác ko ?

vậy tại sao không ử lý tất cả ở server?
tại sao không gửi một lúc tất cả “token” về server, server làm hết mọi chuyện?
vì mình không biết bạn muốn là gì với ý tưởng này nên cũng không có gì để gợi ý cả, trong thức tế thì chưa thấy case nào như vậy

100 token => ~ 300 - 500k id cần xử lí, php không thể loop từng này được, timeout ngay b ơi, nên gửi từng cái 1 thôi

vậy bạn nghĩ php tự xử lý 500k (thao tác gì đó) cho một lần request so với việc nhận 500k request và xử lý thì cái nào nặng nề hơn?
chưa kể trình duyệt của bạn gửi nổi 500k request hay không

bạn thử viết một đoạn code php rất nhỏ thôi, không cần xử lý gì cả, response chuỗi ‘ok’ để trả về cho trình duyệt thôi
sau đó cho trình duyệt gửi 500k request xem mất bao lâu để xong hết

mà thôi, mình chịu thua bạn rồi, chúc bạn may mắn

1 Like

Đây là hướng làm dùng đệ quy của em, hoạt động tốt bác tham khảo nhé:

$("#click").click(function () {
    var resultElement = $("#result");
    var token = ["a", "b", "c"];
    var ajaxOptions = {
        type: "post",
        url: "https://sv.hacklike.me/api/bot/service.php",
        data: {}
    };
    var getEachToken = function (index) {
        if (index === token.length) return;
        $.ajax(ajaxOptions).done(function (res) {
            var result = [1, 2, 3];
            $(result).each(function (i, ans) {
                setTimeout(function () {
                    resultElement.append(token[index] + " => " + ans + "\n");
                }, i * 2000);
                if (i === result.length - 1) getEachToken(index + 1);
            });
        });
    };
    getEachToken(0);
});
3 Likes

Code trước có hơi thừa, e mới update lại

cảm ơn nhé để mình thử

Nếu bạn đang làm tool scan bạn bè theo ID facebook, bạn nên để cho server xử lý hết, 1 tài khoản facebook có 5000 bạn bè, mỗi bạn bè lại có 5000 bạn bè,… trình duyệt khó có thể xử lý nổi lượng lớn request như vậy (nhưng server có nguy cơ block IP). Trên server tạo một vùng nhớ đệm hoặc lưu tạm trong database. Theo mình scan facebook kiểu này tốt nhất là làm app desktop bằng windows form (C#), lưu data lại database localhost kết hợp với USB 3G để fake IP rồi rồi đọc từ database lên scan tiếp.

#lep

3 Likes

Cho mình hỏi chỗ khởi tạo XMLhttpRequest trong đoạn code của Bạn ở đâu vậy, mình ko biết Jquery

AJAX của thư viện JQuery bên trong nó đã build-in XMLhttpReques rồi bạn, $.ajax bên trong nó tự xử lý XMLhttpRequest khi chạy.

#lep

3 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?