30/09/2018, 17:50

Xin một ví dụ giải thích callback trong Javascript là non-blocking?

Đã làm nhiều và biết lý thuyết , rằng CallBack là hàm đc gọi khi thực hiện xong , nó là non-blocking giúp chương trình không phải chờ đợi lần lượt mà sẽ ưu tiên những công việc khác , đến khi nào callBack thực hiện thành công thì sẽ đưa ra kết quả . Nhưng mình mới chỉ biết trên lý thuyết , có bạn nào hiểu thì cho mình 1 ví dụ thực tiễn đến thấy rõ giá trị của nó không . Thanks các bạn nhiều .
P/S : đã tra nhiều trên google nhưng họ chỉ hướng dẫn các xử dụng callback chứ không chỉ rõ ra tác dụng và thấy rõ đc hiệu năng của nó .

vũ xuân quân viết 19:51 ngày 30/09/2018

mình cũng đang học về javascript và nodejs. Bạn tham khảo link dưới. Link này chỉ khái niệm về callback.

techmaster.vn

Event Loop trong Javascript

Một trong khái niệm khá trừu tượng và khó hiểu trong Javascript là Event Loop (vòng lặp xử lý sự kiến). Có nhiều người có thể đã lập trình Javascript trong nhiều năm nhưng không thật sự hiểu chính xác Event loop trong Javascript làm gì. Vì vậy,...

Võ Hoài Nam viết 20:02 ngày 30/09/2018

Mình xin lấy cái ví dụ này để minh họa cho hàm callback… Đọc xong đi, nếu chưa hiểu thì đọc hết comment của mình rồi hãy ý kiến nha

// First style

function funcParent(text, callback) {
    console.log(text);
    
    callback(text);
}

function funcCallback(text) {
    console.log('Callback: ' + text);
}

funcParent('Hello World', funcCallback);

// Second style

function funcParent(text, callback) {
    console.log(text);
    
    callback(text);
}

funcParent('Hello World', function(text) {
    console.log('Callback: ' + text);
});

Vấn đề của @DucDuong_94 đề cập, mình xin tách làm 2 vấn đề…

nó là non-blocking giúp chương trình không phải chờ đợi lần lượt mà sẽ ưu tiên những công việc khác

Chẳng hạn, ta có đoạn mã thế này.

getDataFromJSON('abc.json');

getDataFromDatabase('mysql', 'database', 'table');

Như cách chạy bình thường của đa số các ngôn ngữ lập trình khác, thì nó sẽ gọi hàm getDataFromJSON, chờ hàm này xử lý xong thì nó mới gọi hàm getDataFromDatabase. Nhưng ở trong JavaScript thì nó cơ bản là bất đồng bộ. Nên đụng thằng nào là gọi thằng đó, nên có thể hiểu là nó sẽ gọi 2 hàm này chạy song song. Đây là non-blocking mà bạn đề cập.

Mình lấy một ví dụ hồi xưa gặp với Node.js…

Đầu tiên, mình gọi hàm readConfig để đọc cấu hình của DB, sau đó dùng hàm getData để lấy dữ liệu.

readConfig();
getData();

Tại sao mình không viết 2 thằng này trong 1 hàm vì cơ bản là nó dài quá Sau khi tách 2 hàm này ra thì… đọc dữ liệu không được vì nó không biết đọc ở đâu do chưa có gắn Config vô kịp

Vấn đề sẽ trở nên đơn giản bằng cách sử dung hàm callback Nó sẽ biến bất đồng bộ thành đồng bộ. Có nghĩa là thằng readConfig chạy rồi rồi mới gọi getData. Cơ bản là nó chạy như đoạn code ban đầu mình viết ấy.

readConfig(getData);

Vấn đề thấy đơn giản vậy thôi… Nhưng cái thằng quỷ callback đôi khi nó lại troll nhau… Bạn @masoivn có thể cũng biết là viết Node.js thì dễ có trường hợp hàm lồng nhau…

funcA(function() {
    console.log('A');

    funcB(function() {
        console.log('B');

        funcC(function() {
            console.log('C');

            // see more

            funcZ(function() {
                console.log('Z');
            });
        });
    });
});

Cái này được coi là điểm không tốt của ngôn ngữ JavaScript.

Khi sử dụng hàm callback, ưu/nhược điểm của nó… Mình đã nói rồi. Mình chỉ nói theo cách hiểu của mình thôi

Mai Anh Dũng viết 19:51 ngày 30/09/2018

Câu trả lời rất hay, rất dễ hiểu về bất đồng bộ.

Về ví dụ nhiều hàm lồng nhau thì ngoài việc khó quản lý ra thì còn gì khác không?

Hoa Hoa viết 20:07 ngày 30/09/2018

Giờ mới biết JS nó như thế luôn! Trước giờ cứ nghĩ là nó chạy theo thứ tự! Hết 1 hàm rồi mới tới hàm khác. Cơ mà trước giờ vẫn thấy nó chạy từng hàm xong mới chạy tiếp hàm khác mà. Chưa thấy nó chạy 2 hàm cùng lúc.

cpt viết 19:51 ngày 30/09/2018

Tiện đây xin hỏi mọi người thường dùng cách nào để chạy đồng bộ callback trong js và cách nào được coi là tốt nhất

Võ Hoài Nam viết 19:52 ngày 30/09/2018

Về ví dụ nhiều hàm lồng nhau thì ngoài việc khó quản lý ra thì còn gì khác không?

Ngoài vụ khó quản lý thì em chưa thấy gì khác cả…

Trước giờ cứ nghĩ là nó chạy theo thứ tự! Hết 1 hàm rồi mới tới hàm khác. Cơ mà trước giờ vẫn thấy nó chạy từng hàm xong mới chạy tiếp hàm khác mà.

Có lẽ cái này để mình coi lại… nhưng nói chứ mình viết nhiều khi còn quáng với nó nữa mà

mọi người thường dùng cách nào để chạy đồng bộ callback trong js và cách nào được coi là tốt nhất

Chả có cái gì là tốt nhất… tùy trường hợp à… giống như là sắp xếp một mảng gồm 10 phần tử mà ngồi cài thuật toán Quicksort là thấy thua rồi

nonStop viết 20:07 ngày 30/09/2018

nên có thể hiểu là nó sẽ gọi 2 hàm này chạy song song. Đây là non-blocking mà bạn đề cập.

Cảm ơn bạn , câu trả lời rất chi tiết .

Trong hình trên NodeJs dùng non- blocking chạy 2 file một lúc nên thời gian đọc file chỉ mất 6 giây , còn blocking mất tới 10 giây .

mình muốn hỏi về vấn đề đa luồng và đơn luồng .trong NodeJs là đơn luồng và non-blocking ( vì đơn luồng nên nodeJs chạy rất nhanh) , cho mình hỏi nó chạy 2 file song song , tức là không đồng bộ không đợi nhau mà làm nhiều việc một lúc . như vậy tại sao lại là đơn luồng được nhỉ ?

thanks bạn .

,

Võ Hoài Nam viết 19:58 ngày 30/09/2018

Vấn đề này mình cũng không rõ nữa… Chắc phải nhờ một ai đó nghiên cứu sâu hơn nữa giải thích

Mai Anh Dũng viết 19:52 ngày 30/09/2018

trong NodeJs là đơn luồng và non-blocking ( vì đơn luồng nên nodeJs chạy rất nhanh) , cho mình hỏi nó chạy 2 file song song , tức là không đồng bộ không đợi nhau mà làm nhiều việc một lúc . như vậy tại sao lại là đơn luồng được nhỉ ?

Đoạn này @DucDuong_94 đọc ở đâu? Đạt nghĩ là gửi lên cho mọi người cùng đọc dễ hình dung hơn.

nonStop viết 20:04 ngày 30/09/2018

em xem Video hướng dẫn này anh ơi , họ nói rất rõ về nodeJs . nhưng có mỗi khúc mắc này em ko hiểu
ở phút thứ : 5:14

Trương Phước Hiệu viết 19:58 ngày 30/09/2018

Hình như ngược ngược rồi anh ơi, em mới newbie nodejs thôi mà em đọc cuốn “node for beginner” thì dùng callback để biến đồng bộ thành bất đồng bộ. Trích trong trang 16 17 của cuốn này( anh lên gg search node for begginer download để down lậu cuốn này chứ ko hiểu sao copy bị lỗi)

Event-drivenasynchronouscallbacks
To understand why Node.js applications have to be written this way, we need to understand how Node.js executes our code. Node’s approach isn’t unique, but the underlying execution modelisdifferentfromruntimeenvironmentslikePython,Ruby, PHP or Java. Let’s take a very simple piece of code like this:

var result = database.query(“SELECT * FROM hugetable”);
console.log(“Hello World”);

Please ignore for now that we haven’t actually talked about connecting to databases before - it’s just an example. The first line queries a database for lots of rows, the second line puts ”Hello World” to the console. Let’sassumethat the databasequeryisreallyslow, thatit hasto read an awful lot of rows, which takes several seconds.
Building the application stack 16
The way we have written this code, the JavaScript interpreter of Node.jsfirsthastoreadthecompleteresultsetfromthedatabase, and then it can execute the console.log() function. If this piece of code actually was, say, PHP, it would work the sameway: readalltheresultsatonce,thenexecutethenextline of code. If this code would be part of a web page script, the user would have to wait several seconds for the page to load. However,intheexecutionmodelofPHP,thiswouldnotbecome a”global”problem: thewebserverstartsitsownPHPprocessfor everyHTTPrequestitreceives. Ifoneoftheserequestsresultsin theexecutionofaslowpieceofcode,itresultsinaslowpageload for this particular user, but other users requesting other pages would not be affected. The execution model of Node.js is different - there is only one single process. If there is a slow database query somewhere in thisprocess,thisaffectsthewholeprocess-everythingcomesto a halt until the slow query has finished. To avoid this, JavaScript, and therefore Node.js, introduces the conceptofevent-driven,asynchronouscallbacks, byutilizingan event loop. Wecanunderstandthisconceptbyanalyzingarewrittenversion of our problematic code:

database.query(“SELECT * FROM hugetable”, function(rows) { var result = rows; });
console.log(“Hello World”);

Here, instead of expecting database.query() to directly return
Building the application stack 17
a result to us, we pass it a second parameter, an anonymous function. In its previous form, our code was synchronous: first do the database query, and only when this is done, then write to the console. Now, Node.js can handle the database request asynchronously. Provided that database.query() is part of an asynchronous library,thisiswhatNode.jsdoes: justasbefore,ittakesthequery and sends it to the database. But instead of waiting for it to be finished, it makes a mental note that says ”When at some point in the future the database server is done and sends the result of the query, then I have to execute the anonymous function that was passed to database.query().” Then, it immediately executes console.log(), and afterwards, it enters the event loop. Node.js continuously cycles through this loop again and again whenever there is nothing else to do, waitingforevents. Eventslike,e.g.,aslowdatabasequeryfinally delivering its results.

nonStop viết 20:02 ngày 30/09/2018

Hình như ngược ngược rồi anh ơi, em mới newbie nodejs thôi mà em đọc cuốn “node for beginner” thì dùng callback để biến đồng bộ thành bất đồng bộ.

Em không hiểu câu hỏi của anh à ? tất nhiên anh biết thế mạnh của NodeJs chính là Non-Blocking , NodeJs gắn liền với lập trình Đơn LuồngNon-blocking . Anh muốn hỏi là NodeJs là lập trình Đơn Luồng nhưng tại sao nó có thể thực hiện 2 việc một lúc ? như thế mà lại gọi là Đơn Luồng ??? có thể anh chưa hiểu rõ về Luồng mong bạn nào hiểu rõ có thể giải thích .

Trương Phước Hiệu viết 19:53 ngày 30/09/2018

Em nói anh kia ma.Anh trên kia nói là callback biến bất đồng bộ thành đồng bộ, trong khi sách node for beginner thì nói ngc lại, trong link này cũng nói thếhttp://www.altitudelabs.com/blog/what-is-the-javascript-event-loop/. Vấn đề của anh nằm trong cuốn node for beginner trang 16 17 gì đó nó có nói. Em on đt ko tiện copy

Võ Hoài Nam viết 20:05 ngày 30/09/2018

Ok… cảm ơn bạn… mình sẽ coi lại vấn đề này…

Lúc trước, mình đã gặp vấn đề với ví dụ mình đưa ra… và mình dùng cách đó để giải quyết…

nonStop viết 20:06 ngày 30/09/2018

stackoverflow.com
foreyez

Why is Node.js single threaded?

node.js
asked by foreyez on 12:25AM - 31 Jul 13

Đã có câu trả lời nhé các bạn . trích từ một câu trả lời chi tiết trên face
" Theo mình hiểu nó là implicit I/O non-blocking.
Các I/O operation chạy rất chậm so với các thao tác khác: đọc file từ đĩa cứng, chờ response từ network …, nên nếu cứ chờ nhau thì rất chậm.
Implicit có nghĩa là các thao tác xử lý I/O sẽ được thực hiện bởi các thư viện bên dưới, hoặc bởi API của OS. Người lập trình không cần quan tâm, như thế chương trình sẽ đơn giản hơn. Như vậy thay vì chờ I/O operation thực hiện xong, chương trình của mình cứ tiếp tục thự hiện các tác vụ khác, lúc sau quay lại, thì đã có output của I/O operation rồi (vd: đọc file thì output là Buffer object ở ram rồi). Còn explicit I/O thì mình phải tự tạo processes và delegate các tác vụ cho chúng. "

Bala Bolo viết 19:57 ngày 30/09/2018

Ví dụ:

var fs = require("fs");
fs.readFileSync("van_ban.txt", function (err, data) {
   console.log("Kết thúc việc đọc nội dung. Nội dung tập tin: " + data);
});
console.log("Đang đọc nội dung tập tin...");

Thì hàm callback sẽ là:

function (err, data) {
   console.log("Kết thúc việc đọc nội dung. Nội dung tập tin: " + data);
}

Xem bài viết chi tiết giải thích về hàm callback là gì trên trang www.hoclaptrinh.org

Không Tên viết 19:56 ngày 30/09/2018

Gọi nodejs là đơn luồng vì ở Server chỉ có duy nhất 1 tiến trình chạy để sử lý tất cả các request của client. Tiến trình chạy theo kiểu over loop khác ở php hay asp mỗi request sẽ có 1 tiến trình xữ lý riêng nên, mỗi request là 1 session thì ở nodejs mọi request đều được xữ lý chung bởi 1 tiến trình vì thế Nodejs thích hợp dùng cho ứng dụng readtime là vì thế.

thanhkhuebkdn2012 viết 19:54 ngày 30/09/2018

theo như mình đọc được từ TutorialsPoint
> Node js is a single threaded application but it support concurrency via

concept of event and callbacks. As every API of Node js are asynchronous
 and being a single thread, it uses async function calls to 
maintain the concurrency. Node uses observer pattern. Node thread keeps 

an event loop and whenever any task get completed, it fires the
corresponding event which signals the event listener function to get
executed.
link

Nguyễn Đức Hoàng viết 20:03 ngày 30/09/2018

bạn thấy cái j không đúng à, nói chính xác là IO nonblock nha bạn, chỉ các thao tác IO mới chạy ở luồng khác và không phải đợi còn lại NOdejs là blocking hết, mình chưa hiểu có j mâu thuẫn ở đây

Khoa Nguyen viết 19:58 ngày 30/09/2018

Luồng ở đây là nhân CPU. Toàn bộ chỉ có 1 process nodejs thực thi lệnh từ đầu tới cuối thôi bạn. Khi chạy code bất đồg bộ thì nó sẽ xếp code lần lượt, xen kẽ để cho process không có thời nghỉ

Bài liên quan
0