NodeJS chạy đơn luồng



  • Mình có đoạn mã như bên dưới:

    • Lớp C2 có hàm dem (đếm). Nhiệm vị của hàm dem đơn giản là in ra thông báo khi nó bắt đầu và kết thúc. đồng thời làm nhiệm vụ đếm từ 1 đến một giá trị mong muốn truyền vào.
    • Hàm thực thi tạo 2 luồng, trong đó khởi tạo đối tượng của lớp C2 và gọi tới hàm dem.
      .+ Luồng thứ nhất mình muốn hàm dem thực thi lâu nên truyền giá trị 200000000
      .+ Luồng thức hai mình muốn hàm dem thực thi nhanh nên truyền giá trị 20

    Theo suy nghĩ ban đầu của mình thì luồng 2 thực thi nhanh nên sẽ kết thúc sớm hơn luồng 1, nhưng kết quả in ra thì thấy luồng 2 chỉ bắt đầu khi luồng 1 đã kết thúc.

    Nguyên nhân có phải do NodeJS chạy đơn luồng không? Bạn nào có thể giải thích trường hợp này giúp mình với.

    class C2 {
        dem(ten, so) {
            let result = 0;
            for (let i = 0; i < so; i++) {
                // tang 1 don vi
                result += 1;
                // in thong bao
                if (i == 0) {
                    console.log(ten + ' bat dau');
                }
                if (i == so - 1) {
                    console.log(ten + ' ket thuc');
                }
            }
            return result;
        }
    }
    
    
    (() => {
        console.log('lan 1');
        setTimeout(function() {
            // truyền giá trị 200000000 mục đích để lâu cho ra kết quả.
            // kết quả có sau 1-2 giây
            let a = new C2().dem('lan 1', 200000000);
            console.log('lan 1 tra ve: ', a);
        }, 0);
        console.log('lan 2');
        setTimeout(function() {
            // truyền giá trị 20 mục đích để nhanh cho ra kết quả.
            // kết quả có sau 1-2 mili giây
            let a = new C2().dem('lan 2', 20);
            console.log('lan 2 tra ve: ', a);
        }, 0);
    })();
    /* Kết quả in ra console
    lan 1
    lan 2
    lan 1 bat dau
    lan 1 ket thuc
    lan 1 tra ve:  200000000
    lan 2 bat dau
    lan 2 ket thuc
    lan 2 tra ve:  20
    */
    
    • . ^
    1


  • Hay đó bạn. Những thực nghiệm như thế này sẽ giúp developer ngày càng hiểu rõ bản chất của ngôn ngữ, lên level rất nhanh :D

    Về câu hỏi của bạn, thì mình có thể trả lời được chút ít. JS engine chỉ xử lý code với 1 luồng duy nhất thôi, từ trên xuống dưới. Những chỗ bạn dùng setTimeout sẽ được quăng vào message queue để khi (đến đúng thời điểm && không có gì khác để xử lý) thì nó mới đem ra thực thi. Ví dụ của bạn đặt timeout = 0 tức là as soon as possible, theo tự nhiên, cái nào vào trước sẽ ra trước (FIFO), do đó đoạn xử lý 200000000 sẽ chạy trước và chiếm dụng luồng, đoạn 20 phải đứng chờ thôi.



  • Chà, nếu như vậy thì NodeJS ko phù hợp cho các việc nặng nhọc. Sẽ tốt hơn nếu sử dụng nó để xử lý trường hợp có nhiều công việc nhưng nhẹ, còn trường hợp ít việc nhưng mà nặng thì có lẽ phải dùng mấy em chạy đa luồng.

    • . ^
    0


  • @vahaha bạn có thể dùng childProcess gọi thread con xử lý song song với main thread. Nhưng nếu tác vụ quá chuyên biệt thì vẫn nên tách hẳn ra 1 service, dùng công nghệ khác cũng chả sao. Bây giờ người ta có xu hướng dùng mấy cái AWS Lambda,Google Cloud Functions... để chạy các dịch vụ dạng serverless.


Log in to reply