diff --git a/1-js/06-advanced-functions/08-settimeout-setinterval/1-output-numbers-100ms/solution.md b/1-js/06-advanced-functions/08-settimeout-setinterval/1-output-numbers-100ms/solution.md index b5b1da7a6..1494b537e 100644 --- a/1-js/06-advanced-functions/08-settimeout-setinterval/1-output-numbers-100ms/solution.md +++ b/1-js/06-advanced-functions/08-settimeout-setinterval/1-output-numbers-100ms/solution.md @@ -1,5 +1,5 @@ -Using `setInterval`: +Sử dụng `setInterval`: ```js run function printNumbers(from, to) { @@ -18,7 +18,7 @@ function printNumbers(from, to) { printNumbers(5, 10); ``` -Using nested `setTimeout`: +Sử dụng `setTimeout` lồng nhau: ```js run @@ -38,9 +38,9 @@ function printNumbers(from, to) { printNumbers(5, 10); ``` -Note that in both solutions, there is an initial delay before the first output. The function is called after `1000ms` the first time. +Lưu ý rằng trong cả hai giải pháp, có độ trễ ban đầu trước đầu ra đầu tiên. Hàm được gọi sau `1000ms` lần đầu tiên. -If we also want the function to run immediately, then we can add an additional call on a separate line, like this: +Nếu chúng ta cũng muốn hàm chạy ngay lập tức, thì chúng ta có thể thêm lệnh gọi bổ sung trên một dòng riêng, như sau: ```js run function printNumbers(from, to) { diff --git a/1-js/06-advanced-functions/08-settimeout-setinterval/1-output-numbers-100ms/task.md b/1-js/06-advanced-functions/08-settimeout-setinterval/1-output-numbers-100ms/task.md index 84bb0c39c..af4e1836f 100644 --- a/1-js/06-advanced-functions/08-settimeout-setinterval/1-output-numbers-100ms/task.md +++ b/1-js/06-advanced-functions/08-settimeout-setinterval/1-output-numbers-100ms/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Output every second +# Đầu ra mỗi giây -Write a function `printNumbers(from, to)` that outputs a number every second, starting from `from` and ending with `to`. +Viết hàm `printNumbers(from, to)` xuất ra một số mỗi giây, bắt đầu từ `from` và kết thúc bằng `to`. -Make two variants of the solution. +Thực hiện hai biến thể của giải pháp. -1. Using `setInterval`. -2. Using nested `setTimeout`. +1. Sử dụng `setInterval`. +2. Sử dụng `setTimeout` lồng nhau. diff --git a/1-js/06-advanced-functions/08-settimeout-setinterval/4-settimeout-result/solution.md b/1-js/06-advanced-functions/08-settimeout-setinterval/4-settimeout-result/solution.md index e652a3b36..9074683cc 100644 --- a/1-js/06-advanced-functions/08-settimeout-setinterval/4-settimeout-result/solution.md +++ b/1-js/06-advanced-functions/08-settimeout-setinterval/4-settimeout-result/solution.md @@ -1,14 +1,14 @@ -Any `setTimeout` will run only after the current code has finished. +Bất kỳ `setTimeout` nào sẽ chỉ chạy sau khi mã hiện tại kết thúc. -The `i` will be the last one: `100000000`. +`i` sẽ là cái cuối cùng: `100000000`. ```js run let i = 0; setTimeout(() => alert(i), 100); // 100000000 -// assume that the time to execute this function is >100ms +// giả sử rằng thời gian để chạy hàm này là >100 mili giây for(let j = 0; j < 100000000; j++) { i++; } diff --git a/1-js/06-advanced-functions/08-settimeout-setinterval/4-settimeout-result/task.md b/1-js/06-advanced-functions/08-settimeout-setinterval/4-settimeout-result/task.md index 667c8ffa6..0fefaec14 100644 --- a/1-js/06-advanced-functions/08-settimeout-setinterval/4-settimeout-result/task.md +++ b/1-js/06-advanced-functions/08-settimeout-setinterval/4-settimeout-result/task.md @@ -2,25 +2,25 @@ importance: 5 --- -# What will setTimeout show? +# setTimeout sẽ hiển thị cái gì? -In the code below there's a `setTimeout` call scheduled, then a heavy calculation is run, that takes more than 100ms to finish. +Trong mã bên dưới có một cuộc gọi `setTimeout` được lên lịch, sau đó một phép tính nặng được chạy, mất hơn 100 mili giây để hoàn thành. -When will the scheduled function run? +Khi nào hàm được lên lịch sẽ chạy? -1. After the loop. -2. Before the loop. -3. In the beginning of the loop. +1. Sau vòng lặp. +2. Trước vòng lặp. +3. Ở đầu vòng lặp. -What is `alert` going to show? +`alert` sẽ hiển thị cái gì? ```js let i = 0; setTimeout(() => alert(i), 100); // ? -// assume that the time to execute this function is >100ms +// giả sử rằng thời gian để chạy hàm này là >100 mili giây for(let j = 0; j < 100000000; j++) { i++; } diff --git a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md index 984102687..0a7017ec3 100644 --- a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md +++ b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md @@ -1,35 +1,35 @@ -# Scheduling: setTimeout and setInterval +# Lên lịch: setTimeout và setInterval -We may decide to execute a function not right now, but at a certain time later. That's called "scheduling a call". +Chúng ta có thể quyết định thực hiện một hàm không phải ngay bây giờ mà vào một thời điểm nhất định sau đó. Đó gọi là "lên lịch cuộc gọi". -There are two methods for it: +Có hai phương pháp cho nó: -- `setTimeout` allows us to run a function once after the interval of time. -- `setInterval` allows us to run a function repeatedly, starting after the interval of time, then repeating continuously at that interval. +- `setTimeout` cho phép chúng ta chạy một hàm một lần sau khoảng thời gian. +- `setInterval` cho phép chúng ta chạy lặp đi lặp lại một hàm, bắt đầu sau khoảng thời gian, sau đó lặp lại liên tục ở khoảng thời gian đó. -These methods are not a part of JavaScript specification. But most environments have the internal scheduler and provide these methods. In particular, they are supported in all browsers and Node.js. +Các phương pháp này không phải là một phần của thông số kỹ thuật JavaScript. Nhưng hầu hết các môi trường đều có bộ lên lịch nội bộ và cung cấp các phương thức này. Đặc biệt, chúng được hỗ trợ trên tất cả các trình duyệt và Node.js. ## setTimeout -The syntax: +Cú pháp: ```js let timerId = setTimeout(func|code, [delay], [arg1], [arg2], ...) ``` -Parameters: +Tham số: `func|code` -: Function or a string of code to execute. -Usually, that's a function. For historical reasons, a string of code can be passed, but that's not recommended. +: Hàm hoặc một chuỗi mã để thực thi. +Thông thường, đó là một hàm. Vì lý do lịch sử, một chuỗi mã có thể được chuyển, nhưng điều đó không được khuyến khích. `delay` -: The delay before run, in milliseconds (1000 ms = 1 second), by default 0. +: Độ trễ trước khi chạy, tính bằng mili giây (1000 ms = 1 giây), theo mặc định là 0. `arg1`, `arg2`... -: Arguments for the function (not supported in IE9-) +: Đối số cho hàm (không được hỗ trợ trong IE9-) -For instance, this code calls `sayHi()` after one second: +Chẳng hạn, mã này gọi `sayHi()` sau một giây: ```js run function sayHi() { @@ -41,7 +41,7 @@ setTimeout(sayHi, 1000); */!* ``` -With arguments: +Với đối số: ```js run function sayHi(phrase, who) { @@ -49,97 +49,97 @@ function sayHi(phrase, who) { } *!* -setTimeout(sayHi, 1000, "Hello", "John"); // Hello, John +setTimeout(sayHi, 1000, "Xin chào", "John"); // Xin chào, John */!* ``` -If the first argument is a string, then JavaScript creates a function from it. +Nếu đối số đầu tiên là một chuỗi, thì JavaScript sẽ tạo một hàm từ nó. -So, this will also work: +Vì vậy, cái này cũng sẽ hoạt động: ```js run no-beautify -setTimeout("alert('Hello')", 1000); +setTimeout("alert('Xin chào')", 1000); ``` -But using strings is not recommended, use arrow functions instead of them, like this: +Nhưng việc sử dụng các chuỗi không được khuyến nghị, hãy sử dụng các arrow function thay vì chúng, như sau: ```js run no-beautify -setTimeout(() => alert('Hello'), 1000); +setTimeout(() => alert('Xin chào'), 1000); ``` -````smart header="Pass a function, but don't run it" -Novice developers sometimes make a mistake by adding brackets `()` after the function: +````smart header="Vượt qua một hàm, nhưng không chạy nó" +Các nhà phát triển mới làm quen đôi khi mắc lỗi khi thêm dấu ngoặc `()` sau hàm: ```js -// wrong! +// sai! setTimeout(sayHi(), 1000); ``` -That doesn't work, because `setTimeout` expects a reference to a function. And here `sayHi()` runs the function, and the *result of its execution* is passed to `setTimeout`. In our case the result of `sayHi()` is `undefined` (the function returns nothing), so nothing is scheduled. +Điều đó không hoạt động, bởi vì `setTimeout` mong đợi một tham chiếu đến một hàm. Và ở đây `sayHi()` chạy hàm này và *kết quả thực thi của nó* được chuyển đến `setTimeout`. Trong trường hợp của chúng ta, kết quả của `sayHi()` là `undefined` (hàm không trả về gì cả), vì vậy không có gì được lên lịch. ```` -### Canceling with clearTimeout +### Hủy với ClearTimeout -A call to `setTimeout` returns a "timer identifier" `timerId` that we can use to cancel the execution. +Một cuộc gọi đến `setTimeout` trả về một "số nhận dạng hẹn giờ" `timerId` mà chúng ta có thể sử dụng để hủy thực thi. -The syntax to cancel: +Cú pháp hủy: ```js let timerId = setTimeout(...); clearTimeout(timerId); ``` -In the code below, we schedule the function and then cancel it (changed our mind). As a result, nothing happens: +Trong mã bên dưới, chúng ta lên lịch cho hàm và sau đó hủy bỏ hàm đó (đã thay đổi ý định). Kết quả là, không có gì xảy ra: ```js run no-beautify -let timerId = setTimeout(() => alert("never happens"), 1000); -alert(timerId); // timer identifier +let timerId = setTimeout(() => alert("không bao giờ xảy ra"), 1000); +alert(timerId); // mã định danh hẹn giờ clearTimeout(timerId); -alert(timerId); // same identifier (doesn't become null after canceling) +alert(timerId); // cùng một mã định danh (không trở thành null sau khi hủy) ``` -As we can see from `alert` output, in a browser the timer identifier is a number. In other environments, this can be something else. For instance, Node.js returns a timer object with additional methods. +Như chúng ta có thể thấy từ đầu ra `alert`, trong trình duyệt, mã định danh hẹn giờ là một số. Trong các môi trường khác, đây có thể là một cái gì đó khác. Chẳng hạn, Node.js trả về một đối tượng hẹn giờ với các phương thức bổ sung. -Again, there is no universal specification for these methods, so that's fine. +Một lần nữa, không có thông số kỹ thuật chung cho các phương pháp này, vì vậy điều đó không sao cả. -For browsers, timers are described in the [timers section](https://www.w3.org/TR/html5/webappapis.html#timers) of HTML5 standard. +Đối với trình duyệt, bộ đếm giờ được mô tả trong phần [bộ đếm giờ](https://www.w3.org/TR/html5/webappapis.html#timers) của chuẩn HTML5. ## setInterval -The `setInterval` method has the same syntax as `setTimeout`: +Phương thức `setInterval` có cùng cú pháp với `setTimeout`: ```js let timerId = setInterval(func|code, [delay], [arg1], [arg2], ...) ``` -All arguments have the same meaning. But unlike `setTimeout` it runs the function not only once, but regularly after the given interval of time. +Tất cả các đối số có cùng một ý nghĩa. Nhưng không giống như `setTimeout`, hàm này không chỉ chạy một lần mà thường xuyên sau một khoảng thời gian nhất định. -To stop further calls, we should call `clearInterval(timerId)`. +Để dừng các cuộc gọi tiếp theo, chúng ta nên gọi `clearInterval(timerId)`. -The following example will show the message every 2 seconds. After 5 seconds, the output is stopped: +Ví dụ sau sẽ hiển thị thông báo cứ sau 2 giây. Sau 5 giây, đầu ra bị dừng: ```js run -// repeat with the interval of 2 seconds +// lặp lại với khoảng thời gian 2 giây let timerId = setInterval(() => alert('tick'), 2000); -// after 5 seconds stop -setTimeout(() => { clearInterval(timerId); alert('stop'); }, 5000); +// sau 5 giây dừng lại +setTimeout(() => { clearInterval(timerId); alert('dừng lại'); }, 5000); ``` -```smart header="Time goes on while `alert` is shown" -In most browsers, including Chrome and Firefox the internal timer continues "ticking" while showing `alert/confirm/prompt`. +```smart header="Thời gian tiếp tục trong khi `alert` được hiển thị" +Trong hầu hết các trình duyệt, kể cả Chrome và Firefox, bộ đếm thời gian bên trong tiếp tục "tích tắc" trong khi hiển thị `alert/confirm/prompt`. -So if you run the code above and don't dismiss the `alert` window for some time, then the next `alert` will be shown immediately as you do it. The actual interval between alerts will be shorter than 2 seconds. +Vì vậy, nếu bạn chạy mã ở trên và không đóng cửa sổ `alert` trong một thời gian, thì `cảnh báo` tiếp theo sẽ được hiển thị ngay lập tức khi bạn thực hiện. Khoảng thời gian thực tế giữa các cảnh báo sẽ ngắn hơn 2 giây. ``` -## Nested setTimeout +## setTimeout lồng nhau -There are two ways of running something regularly. +Có hai cách để chạy một cái gì đó thường xuyên. -One is `setInterval`. The other one is a nested `setTimeout`, like this: +Một là `setInterval`. Cái còn lại là `setTimeout` lồng nhau, như thế này: ```js -/** instead of: +/** thay vì: let timerId = setInterval(() => alert('tick'), 2000); */ @@ -151,21 +151,21 @@ let timerId = setTimeout(function tick() { }, 2000); ``` -The `setTimeout` above schedules the next call right at the end of the current one `(*)`. +`setTimeout` ở trên lên lịch cuộc gọi tiếp theo ngay khi kết thúc cuộc gọi hiện tại `(*)`. -The nested `setTimeout` is a more flexible method than `setInterval`. This way the next call may be scheduled differently, depending on the results of the current one. +`setTimeout` lồng nhau là một phương thức linh hoạt hơn `setInterval`. Bằng cách này, cuộc gọi tiếp theo có thể được lên lịch khác nhau, tùy thuộc vào kết quả của cuộc gọi hiện tại. -For instance, we need to write a service that sends a request to the server every 5 seconds asking for data, but in case the server is overloaded, it should increase the interval to 10, 20, 40 seconds... +Ví dụ chúng ta cần viết một dịch vụ cứ 5 giây lại gửi một yêu cầu đến server yêu cầu dữ liệu, nhưng trong trường hợp server bị quá tải thì nên tăng khoảng thời gian lên 10, 20, 40 giây... -Here's the pseudocode: +Đây là mã giả: ```js let delay = 5000; let timerId = setTimeout(function request() { - ...send request... + ...gửi yêu cầu... - if (request failed due to server overload) { - // increase the interval to the next run + if (yêu cầu không thành công do quá tải máy chủ) { + // tăng khoảng thời gian cho lần chạy tiếp theo delay *= 2; } @@ -175,11 +175,11 @@ let timerId = setTimeout(function request() { ``` -And if the functions that we're scheduling are CPU-hungry, then we can measure the time taken by the execution and plan the next call sooner or later. +Và nếu các hàm mà chúng ta đang lập lịch sử dụng nhiều CPU, thì chúng ta có thể đo thời gian thực hiện và lập kế hoạch cho cuộc gọi tiếp theo sớm hay muộn. -**Nested `setTimeout` allows to set the delay between the executions more precisely than `setInterval`.** +**`setTimeout` lồng nhau cho phép đặt độ trễ giữa các lần thực thi chính xác hơn `setInterval`.** -Let's compare two code fragments. The first one uses `setInterval`: +Hãy so sánh hai đoạn mã. Cái đầu tiên sử dụng `setInterval`: ```js let i = 1; @@ -188,7 +188,7 @@ setInterval(function() { }, 100); ``` -The second one uses nested `setTimeout`: +Cái thứ hai sử dụng `setTimeout` lồng nhau: ```js let i = 1; @@ -198,105 +198,105 @@ setTimeout(function run() { }, 100); ``` -For `setInterval` the internal scheduler will run `func(i++)` every 100ms: +Đối với `setInterval`, bộ lên lịch nội bộ sẽ chạy `func(i++)` cứ sau 100 mili giây: ![](setinterval-interval.svg) -Did you notice? +Bạn có để ý không? -**The real delay between `func` calls for `setInterval` is less than in the code!** +**Độ trễ thực sự giữa các lệnh gọi `func` cho `setInterval` nhỏ hơn trong mã!** -That's normal, because the time taken by `func`'s execution "consumes" a part of the interval. +Điều đó là bình thường, bởi vì thời gian thực thi của `func` "tiêu tốn" một phần của khoảng thời gian. -It is possible that `func`'s execution turns out to be longer than we expected and takes more than 100ms. +Có thể quá trình thực thi của `func` kéo dài hơn chúng ta mong đợi và mất hơn 100 mili giây. -In this case the engine waits for `func` to complete, then checks the scheduler and if the time is up, runs it again *immediately*. +Trong trường hợp này, engine đợi `func` hoàn thành, sau đó kiểm tra bộ lên lịch và nếu hết thời gian, hãy chạy lại *ngay lập tức*. -In the edge case, if the function always executes longer than `delay` ms, then the calls will happen without a pause at all. +Trong trường hợp cạnh, nếu hàm luôn thực thi lâu hơn `delay` ms, thì các cuộc gọi sẽ diễn ra mà không có khoảng dừng nào cả. -And here is the picture for the nested `setTimeout`: +Và đây là hình ảnh cho `setTimeout` lồng nhau: ![](settimeout-interval.svg) -**The nested `setTimeout` guarantees the fixed delay (here 100ms).** +**`setTimeout` lồng nhau đảm bảo độ trễ cố định (ở đây là 100 mili giây).** -That's because a new call is planned at the end of the previous one. +Đó là bởi vì một cuộc gọi mới được lên kế hoạch vào cuối cuộc gọi trước đó. -````smart header="Garbage collection and setInterval/setTimeout callback" -When a function is passed in `setInterval/setTimeout`, an internal reference is created to it and saved in the scheduler. It prevents the function from being garbage collected, even if there are no other references to it. +````smart header="Thu gom rác và gọi lại setInterval/setTimeout" +Khi một chức năng được chuyển vào `setInterval/setTimeout`, một tham chiếu nội bộ được tạo cho nó và được lưu trong bộ lên lịch. Nó ngăn hàm bị thu gom rác, ngay cả khi không có tham chiếu nào khác đến nó. ```js -// the function stays in memory until the scheduler calls it +// hàm vẫn còn trong bộ nhớ cho đến khi bộ lên lịch gọi nó setTimeout(function() {...}, 100); ``` -For `setInterval` the function stays in memory until `clearInterval` is called. +Đối với `setInterval`, hàm này sẽ nằm trong bộ nhớ cho đến khi `clearInterval` được gọi. -There's a side-effect. A function references the outer lexical environment, so, while it lives, outer variables live too. They may take much more memory than the function itself. So when we don't need the scheduled function anymore, it's better to cancel it, even if it's very small. +Có một tác dụng phụ. Một hàm tham chiếu đến lexical environment bên ngoài, vì vậy, trong khi nó hoạt động, các biến bên ngoài cũng hoạt động. Chúng có thể chiếm nhiều bộ nhớ hơn chính hàm đó. Vì vậy, khi chúng ta không cần đến hàm đã lên lịch nữa, tốt hơn hết là hủy bỏ nó, ngay cả khi nó rất nhỏ. ```` -## Zero delay setTimeout +## setTimeout không độ trễ -There's a special use case: `setTimeout(func, 0)`, or just `setTimeout(func)`. +Có một trường hợp sử dụng đặc biệt: `setTimeout(func, 0)` hay chỉ `setTimeout(func)`. -This schedules the execution of `func` as soon as possible. But the scheduler will invoke it only after the currently executing script is complete. +Điều này lên lịch thực hiện `func` càng sớm càng tốt. Nhưng bộ lên lịch sẽ gọi nó chỉ sau khi tập lệnh hiện đang thực thi hoàn tất. -So the function is scheduled to run "right after" the current script. +Vì vậy, hàm được lên lịch để chạy "ngay sau" tập lệnh hiện tại. -For instance, this outputs "Hello", then immediately "World": +Chẳng hạn, kết quả này xuất ra "Xin chào", sau đó ngay lập tức là "Thế giới": ```js run -setTimeout(() => alert("World")); +setTimeout(() => alert("Thế giới")); -alert("Hello"); +alert("Xin chào"); ``` -The first line "puts the call into calendar after 0ms". But the scheduler will only "check the calendar" after the current script is complete, so `"Hello"` is first, and `"World"` -- after it. +Dòng đầu tiên "đặt cuộc gọi vào lịch sau 0ms". Nhưng bộ lên lịch sẽ chỉ "kiểm tra lịch" sau khi tập lệnh hiện tại hoàn tất, vì vậy `"Xin chào"` sẽ ở vị trí đầu tiên và `"Thế giới"` -- sau tập lệnh đó. -There are also advanced browser-related use cases of zero-delay timeout, that we'll discuss in the chapter . +Ngoài ra còn có các trường hợp sử dụng thời gian chờ không chậm trễ liên quan đến trình duyệt nâng cao mà chúng ta sẽ thảo luận trong chương . -````smart header="Zero delay is in fact not zero (in a browser)" -In the browser, there's a limitation of how often nested timers can run. The [HTML5 standard](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) says: "after five nested timers, the interval is forced to be at least 4 milliseconds.". +````smart header="Độ trễ bằng không trên thực tế không phải bằng không (trong trình duyệt)" +Trong trình duyệt, có giới hạn về tần suất chạy các bộ đếm giờ lồng nhau. [Chuẩn HTML5](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) nói: "sau năm bộ đếm giờ lồng nhau, khoảng thời gian buộc phải ít nhất là 4 mili giây.". -Let's demonstrate what it means with the example below. The `setTimeout` call in it re-schedules itself with zero delay. Each call remembers the real time from the previous one in the `times` array. What do the real delays look like? Let's see: +Hãy chứng minh ý nghĩa của nó với ví dụ dưới đây. Cuộc gọi `setTimeout` trong đó sẽ tự lên lịch lại mà không có độ trễ bằng không. Mỗi cuộc gọi ghi nhớ thời gian thực từ cuộc gọi trước đó trong array `times`. Sự chậm trễ thực sự trông như thế nào? Hãy xem nào: ```js run let start = Date.now(); let times = []; setTimeout(function run() { - times.push(Date.now() - start); // remember delay from the previous call + times.push(Date.now() - start); // ghi nhớ độ trễ từ cuộc gọi trước - if (start + 100 < Date.now()) alert(times); // show the delays after 100ms - else setTimeout(run); // else re-schedule + if (start + 100 < Date.now()) alert(times); // hiển thị độ trễ sau 100ms + else setTimeout(run); // lên lại lịch khác }); -// an example of the output: +// một ví dụ về đầu ra: // 1,1,1,1,9,15,20,24,30,35,40,45,50,55,59,64,70,75,80,85,90,95,100 ``` -First timers run immediately (just as written in the spec), and then we see `9, 15, 20, 24...`. The 4+ ms obligatory delay between invocations comes into play. +Bộ hẹn giờ đầu tiên chạy ngay lập tức (giống như được viết trong thông số kỹ thuật), và sau đó chúng ta thấy `9, 15, 20, 24...`. Độ trễ bắt buộc hơn 4 ms giữa các lần gọi bắt đầu phát huy tác dụng. -The similar thing happens if we use `setInterval` instead of `setTimeout`: `setInterval(f)` runs `f` few times with zero-delay, and afterwards with 4+ ms delay. +Điều tương tự cũng xảy ra nếu chúng ta sử dụng `setInterval` thay vì `setTimeout`: `setInterval(f)` chạy `f` vài lần với độ trễ bằng 0 và sau đó với độ trễ hơn 4 ms. -That limitation comes from ancient times and many scripts rely on it, so it exists for historical reasons. +Hạn chế đó có từ trước và nhiều tập lễnh dựa vào đó mà tồn tại vì những lý do lịch sử. -For server-side JavaScript, that limitation does not exist, and there exist other ways to schedule an immediate asynchronous job, like [setImmediate](https://nodejs.org/api/timers.html#timers_setimmediate_callback_args) for Node.js. So this note is browser-specific. +Đối với JavaScript phía máy chủ, giới hạn đó không tồn tại và tồn tại các cách khác để lên lịch cho một công việc không đồng bộ ngay lập tức, chẳng hạn như [setImmediate](https://nodejs.org/api/timers.html#timers_setimmediate_callback_args) cho Node.js. Vì vậy, ghi chú này là dành riêng cho trình duyệt. ```` -## Summary +## Tóm tắt -- Methods `setTimeout(func, delay, ...args)` and `setInterval(func, delay, ...args)` allow us to run the `func` once/regularly after `delay` milliseconds. -- To cancel the execution, we should call `clearTimeout/clearInterval` with the value returned by `setTimeout/setInterval`. -- Nested `setTimeout` calls are a more flexible alternative to `setInterval`, allowing us to set the time *between* executions more precisely. -- Zero delay scheduling with `setTimeout(func, 0)` (the same as `setTimeout(func)`) is used to schedule the call "as soon as possible, but after the current script is complete". -- The browser limits the minimal delay for five or more nested calls of `setTimeout` or for `setInterval` (after 5th call) to 4ms. That's for historical reasons. +- Các phương thức `setTimeout(func, delay, ...args)` và `setInterval(func, delay, ...args)` cho phép chúng ta chạy `func` một lần/thường xuyên sau `delay` mili giây. +- Để hủy thực thi, chúng ta nên gọi `clearTimeout/clearInterval` với giá trị được trả về bởi `setTimeout/setInterval`. +- Các lệnh gọi `setTimeout` lồng nhau là một giải pháp thay thế linh hoạt hơn cho `setInterval`, cho phép chúng ta đặt thời gian *giữa* các lần thực thi chính xác hơn. +- Lên lịch không độ trễ với `setTimeout(func, 0)` (giống như `setTimeout(func)`) được sử dụng để lên lịch cuộc gọi "càng sớm càng tốt, nhưng sau khi tập lệnh hiện tại hoàn tất". +- Trình duyệt giới hạn độ trễ tối thiểu cho năm lệnh gọi lồng nhau trở lên của `setTimeout` hoặc cho `setInterval` (sau lệnh gọi thứ 5) là 4 mili giây. Đó là vì lý do lịch sử. -Please note that all scheduling methods do not *guarantee* the exact delay. +Hãy lưu ý rằng tất cả các phương pháp lên lịch không *đảm bảo* độ trễ chính xác. -For example, the in-browser timer may slow down for a lot of reasons: -- The CPU is overloaded. -- The browser tab is in the background mode. -- The laptop is on battery. +Ví dụ: bộ đếm giờ trong trình duyệt có thể chậm lại vì nhiều lý do: +- CPU bị quá tải. +- Tab trình duyệt đang ở chế độ nền. +- Laptop đang hết pin. -All that may increase the minimal timer resolution (the minimal delay) to 300ms or even 1000ms depending on the browser and OS-level performance settings. +Tất cả những điều đó có thể làm tăng độ phân giải bộ đếm giờ tối thiểu (độ trễ tối thiểu) lên 300 mili giây hoặc thậm chí 1000 mili giây tùy thuộc vào cài đặt hiệu suất ở cấp hệ điều hành và trình duyệt.