Trong Javascript, có đồng bộ và không đồng bộ chức năng.
Chức năng đồng bộ
Hầu hết các chức năng trong Javascript là đồng bộ. Nếu bạn đã gọi một số chức năng đồng bộ liên tiếp
doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
họ sẽ thực hiện theo thứ tự. doSomethingElse
sẽ không bắt đầu cho đến khi doSomething
hoàn thành. doSomethingUsefulThisTime
, lần lượt, sẽ không bắt đầu cho đến khi doSomethingElse
hoàn thành.
Hàm không đồng bộ
Tuy nhiên, chức năng không đồng bộ sẽ không chờ nhau. Chúng ta hãy xem xét cùng một mẫu mã mà chúng ta đã có ở trên, lần này giả sử rằng các hàm không đồng bộ
doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
Các chức năng sẽ được khởi tạo theo thứ tự, nhưng tất cả chúng sẽ thực hiện gần như cùng một lúc. Bạn không thể dự đoán một cách nhất quán cái nào sẽ hoàn thành trước: cái nào xảy ra trong khoảng thời gian ngắn nhất để thực hiện sẽ hoàn thành trước.
Nhưng đôi khi, bạn muốn các hàm không đồng bộ thực hiện theo thứ tự và đôi khi bạn muốn các hàm được đồng bộ hóa để thực thi không đồng bộ. May mắn thay, điều này là có thể với các cuộc gọi lại và thời gian chờ, tương ứng.
Gọi lại
Giả sử rằng chúng ta có ba chức năng không đồng bộ mà chúng ta muốn thực hiện theo thứ tự, some_3secs_function
, some_5secs_function
, và some_8secs_function
.
Vì các hàm có thể được truyền dưới dạng đối số trong Javascript, bạn có thể truyền một hàm dưới dạng gọi lại để thực thi sau khi hàm hoàn thành.
Nếu chúng ta tạo các hàm như thế này
function some_3secs_function(value, callback){
//do stuff
callback();
}
sau đó bạn có thể gọi sau đó theo thứ tự, như thế này:
some_3secs_function(some_value, function() {
some_5secs_function(other_value, function() {
some_8secs_function(third_value, function() {
//All three functions have completed, in order.
});
});
});
Hết giờ
Trong Javascript, bạn có thể yêu cầu một chức năng thực thi sau một khoảng thời gian chờ nhất định (tính bằng mili giây). Điều này có thể, trong thực tế, làm cho các chức năng đồng bộ hoạt động không đồng bộ.
Nếu chúng ta có ba hàm đồng bộ, chúng ta có thể thực thi chúng không đồng bộ bằng cách sử dụng setTimeout
hàm.
setTimeout(doSomething, 10);
setTimeout(doSomethingElse, 10);
setTimeout(doSomethingUsefulThisTime, 10);
Tuy nhiên, điều này hơi xấu và vi phạm nguyên tắc DRY [wikipedia] . Chúng ta có thể làm sạch điều này một chút bằng cách tạo một hàm chấp nhận một mảng các hàm và thời gian chờ.
function executeAsynchronously(functions, timeout) {
for(var i = 0; i < functions.length; i++) {
setTimeout(functions[i], timeout);
}
}
Điều này có thể được gọi như vậy:
executeAsynchronously(
[doSomething, doSomethingElse, doSomethingUsefulThisTime], 10);
Tóm lại, nếu bạn có các hàm không đồng bộ mà bạn muốn thực thi đồng bộ hóa, hãy sử dụng các hàm gọi lại và nếu bạn có các hàm đồng bộ mà bạn muốn thực thi không đồng bộ, hãy sử dụng thời gian chờ.