Câu trả lời:
Có những điều sau đây:
setTimeout(function, milliseconds);
Hàm có thể được chuyển qua thời gian sau đó hàm sẽ được thực thi.
Xem: Phương pháp cửa sổsetTimeout()
.
function_reference
trừ khi bạn bao gồm ()
. Tức function_reference
là chỉ có thế - một tài liệu tham khảo; đi vào function_reference()
sẽ gọi hàm ngay lập tức.
Chỉ cần thêm vào những gì mọi người khác đã nói về setTimeout
: Nếu bạn muốn gọi một hàm với một tham số trong tương lai, bạn cần thiết lập một số lệnh gọi hàm ẩn danh.
Bạn cần truyền hàm dưới dạng đối số để nó được gọi sau. Trong thực tế điều này có nghĩa là không có dấu ngoặc phía sau tên. Sau đây sẽ gọi cảnh báo cùng một lúc và nó sẽ hiển thị 'Xin chào thế giới':
var a = "world";
setTimeout(alert("Hello " + a), 2000);
Để khắc phục điều này, bạn có thể đặt tên của một hàm (như Flubba đã làm) hoặc bạn có thể sử dụng một hàm ẩn danh. Nếu bạn cần truyền tham số, thì bạn phải sử dụng hàm ẩn danh.
var a = "world";
setTimeout(function(){alert("Hello " + a)}, 2000);
a = "Stack Overflow";
Nhưng nếu bạn chạy mã đó, bạn sẽ nhận thấy rằng sau 2 giây, cửa sổ bật lên sẽ thông báo 'Xin chào tràn chồng'. Điều này là do giá trị của biến a đã thay đổi trong hai giây đó. Để làm cho nó nói 'Xin chào thế giới' sau hai giây, bạn cần sử dụng đoạn mã sau:
function callback(a){
return function(){
alert("Hello " + a);
}
}
var a = "world";
setTimeout(callback(a), 2000);
a = "Stack Overflow";
Nó sẽ đợi 2 giây và sau đó bật lên 'Xin chào thế giới'.
Nếu bạn thực sự muốn có delay
chức năng chặn (đồng bộ) (cho bất cứ điều gì), tại sao không làm điều gì đó như thế này:
<script type="text/javascript">
function delay(ms) {
var cur_d = new Date();
var cur_ticks = cur_d.getTime();
var ms_passed = 0;
while(ms_passed < ms) {
var d = new Date(); // Possible memory leak?
var ticks = d.getTime();
ms_passed = ticks - cur_ticks;
// d = null; // Prevent memory leak?
}
}
alert("2 sec delay")
delay(2000);
alert("done ... 500 ms delay")
delay(500);
alert("done");
</script>
delay
ing (để trả lời câu hỏi này ). Có cách nào để làm như vậy?
Bạn cần sử dụng setTimeout và truyền cho nó chức năng gọi lại. Lý do bạn không thể sử dụng chế độ ngủ trong javascript là vì bạn chặn toàn bộ trang không làm gì trong lúc này. Không phải là một kế hoạch tốt. Sử dụng mô hình sự kiện của Javascript và luôn vui vẻ. Đừng chiến đấu với nó!
Bạn cũng có thể sử dụng window.setInterval () để chạy một số mã liên tục trong một khoảng thời gian thông thường.
setTimeout()
làm một lần, setInterval()
làm nhiều lần Nếu bạn muốn mã của bạn chạy cứ sau 5 giây, setInterval()
được tạo cho công việc.
Để thêm vào các ý kiến trước đó, tôi muốn nói như sau:
Các setTimeout()
hàm trong JavaScript không tạm dừng thực hiện các kịch bản cho mỗi gia nhập, mà chỉ nói với trình biên dịch để thực hiện đôi khi mã trong tương lai.
Không có chức năng nào thực sự có thể tạm dừng thực thi được tích hợp trong JavaScript. Tuy nhiên, bạn có thể viết hàm riêng thực hiện một vòng lặp vô điều kiện cho đến khi đạt được thời gian bằng cách sử dụng Date()
hàm và thêm khoảng thời gian bạn cần.
Nếu bạn chỉ cần kiểm tra độ trễ, bạn có thể sử dụng:
function delay(ms) {
ms += new Date().getTime();
while (new Date() < ms){}
}
Và sau đó nếu bạn muốn trì hoãn trong 2 giây, bạn làm:
delay(2000);
Có thể không phải là tốt nhất cho sản xuất mặc dù. Thêm vào đó trong các ý kiến
Tại sao bạn không thể đặt mã đằng sau một lời hứa? (gõ vào đỉnh đầu của tôi)
new Promise(function(resolve, reject) {
setTimeout(resolve, 2000);
}).then(function() {
console.log('do whatever you wanted to hold off on');
});
Tôi thực sự thích lời giải thích của Maurius (phản hồi được nâng cao nhất) với ba phương thức khác nhau để gọi setTimeout
.
Trong mã của tôi, tôi muốn tự động điều hướng đến trang trước khi hoàn thành sự kiện lưu AJAX. Việc hoàn thành sự kiện lưu có một hình ảnh động nhỏ trong CSS cho thấy việc lưu đã thành công.
Trong mã của tôi, tôi tìm thấy một sự khác biệt giữa hai ví dụ đầu tiên:
setTimeout(window.history.back(), 3000);
Cái này không chờ thời gian chờ - back () được gọi gần như ngay lập tức bất kể số tôi đặt vào cho độ trễ.
Tuy nhiên, thay đổi điều này thành:
setTimeout(function() {window.history.back()}, 3000);
Điều này làm chính xác những gì tôi đã hy vọng.
Điều này không đặc trưng cho hoạt động back (), điều tương tự cũng xảy ra với alert()
. Về cơ bản với việc alert()
sử dụng trong trường hợp đầu tiên, thời gian trễ được bỏ qua. Khi tôi bỏ qua cửa sổ bật lên, hình ảnh động cho CSS tiếp tục.
Vì vậy, tôi muốn giới thiệu phương thức thứ hai hoặc thứ ba mà anh mô tả ngay cả khi bạn đang sử dụng các hàm dựng sẵn và không sử dụng các đối số.
Tôi đã có một số lệnh ajax tôi muốn chạy với độ trễ ở giữa. Đây là một ví dụ đơn giản về một cách để làm điều đó. Tôi đã chuẩn bị để bị xé vụn mặc dù cho cách tiếp cận độc đáo của tôi. :)
// Show current seconds and milliseconds
// (I know there are other ways, I was aiming for minimal code
// and fixed width.)
function secs()
{
var s = Date.now() + ""; s = s.substr(s.length - 5);
return s.substr(0, 2) + "." + s.substr(2);
}
// Log we're loading
console.log("Loading: " + secs());
// Create a list of commands to execute
var cmds =
[
function() { console.log("A: " + secs()); },
function() { console.log("B: " + secs()); },
function() { console.log("C: " + secs()); },
function() { console.log("D: " + secs()); },
function() { console.log("E: " + secs()); },
function() { console.log("done: " + secs()); }
];
// Run each command with a second delay in between
var ms = 1000;
cmds.forEach(function(cmd, i)
{
setTimeout(cmd, ms * i);
});
// Log we've loaded (probably logged before first command)
console.log("Loaded: " + secs());
Bạn có thể sao chép khối mã và dán nó vào cửa sổ giao diện điều khiển và xem một cái gì đó như:
Loading: 03.077
Loaded: 03.078
A: 03.079
B: 04.075
C: 05.075
D: 06.075
E: 07.076
done: 08.076
chức năng trì hoãn:
/**
* delay or pause for some time
* @param {number} t - time (ms)
* @return {Promise<*>}
*/
const delay = async t => new Promise(resolve => setTimeout(resolve, t));
sử dụng async
chức năng bên trong :
await delay(1000);
Như đã nói, setTimeout là đặt cược an toàn nhất của bạn
Nhưng đôi khi bạn không thể tách logic thành một hàm mới thì bạn có thể sử dụng Date.now () để nhận mili giây và tự mình trì hoãn ....
function delay(milisecondDelay) {
milisecondDelay += Date.now();
while(Date.now() < milisecondDelay){}
}
alert('Ill be back in 5 sec after you click OK....');
delay(5000);
alert('# Im back # date:' +new Date());