Ответы:
Вы можете использовать setTimeout
для достижения аналогичного эффекта:
var a = 1 + 3;
var b;
setTimeout(function() {
b = a + 4;
}, (3 * 1000));
На самом деле это не «спящий» JavaScript - он просто выполняет переданную функцию по setTimeout
истечении определенного времени (указанного в миллисекундах). Хотя можно написать функцию сна для JavaScript, по возможности лучше использовать, setTimeout
поскольку она не замораживает все в течение периода сна.
Если вам действительно нужно sleep()
что-то протестировать. Но имейте в виду, что во время отладки в большинстве случаев это приведет к сбою браузера - вероятно, поэтому он вам все равно нужен. В производственном режиме я закомментирую эту функцию.
function pauseBrowser(millis) {
var date = Date.now();
var curDate = null;
do {
curDate = Date.now();
} while (curDate-date < millis);
}
Не используйте new Date()
в цикле, если вы не хотите тратить впустую память, вычислительную мощность, батарею и, возможно, весь срок службы вашего устройства.
Версия ECMAScript 6, использующая генераторы с yield для «блокировки кода»:
Поскольку исходный вопрос был опубликован семь лет назад, я не стал отвечать точным кодом, потому что это слишком просто и уже дан ответ. Это должно помочь в более сложных проблемах, например, если вам нужно как минимум два сна или если вы планируете упорядочить асинхронное выполнение. Не стесняйтесь изменять его под свои нужды.
let sleeptime = 100
function* clock()
{
let i = 0
while( i <= 10000 )
{
i++
console.log(i); // actually, just do stuff you wanna do.
setTimeout(
()=>
{
clk.next()
}
, sleeptime
)
yield
}
}
let clk = clock()
clk.next()
Вы также можете связать события через обещания :
function sleep(ms)
{
return(
new Promise(function(resolve, reject)
{
setTimeout(function() { resolve(); }, ms);
})
);
}
sleep(1000).then(function()
{
console.log('1')
sleep(1000).then(function()
{
console.log('2')
})
})
Или гораздо более простой и менее изящный способ был бы
function sleep(ms, f)
{
return(
setTimeout(f, ms)
)
}
sleep(500, function()
{
console.log('1')
sleep(500, function()
{
console.log('2')
})
})
console.log('Event chain launched')
Если вы просто ждете, когда произойдет какое-то условие, вы можете подождать вот так
function waitTill(condition, thenDo)
{
if (eval(condition))
{
thenDo()
return
}
setTimeout(
() =>
{
waitTill(condition, thenDo)
}
,
1
)
}
x=0
waitTill(
'x>2 || x==1'
,
() =>
{
console.log("Conditions met!")
}
)
// Simulating the change
setTimeout(
() =>
{
x = 1
}
,
1000
)
Последние версии Safari, Firefox и Node.js теперь также поддерживают async / await / promises.
(С 1/2017 поддерживается в Chrome, но не в Safari, Internet Explorer, Firefox, Node.js)
'use strict';
function sleep(ms) {
return new Promise(res => setTimeout(res, ms));
}
let myAsyncFunc = async function() {
console.log('Sleeping');
await sleep(3000);
console.log('Done');
}
myAsyncFunc();
JavaScript эволюционировал с тех пор, как был задан этот вопрос, и теперь у него есть функции генератора, а также выпускается новый async / await / Promise. Ниже приведены два решения: одно с функцией генератора, которое будет работать во всех современных браузерах, а другое, использующее новый async / await, который еще не поддерживается повсеместно.
'use strict';
let myAsync = (g) => (...args) => {
let f, res = () => f.next(),
sleep = (ms) => setTimeout(res, ms);
f = g.apply({sleep}, args); f.next();
};
let myAsyncFunc = myAsync(function*() {
let {sleep} = this;
console.log("Sleeping");
yield sleep(3000);
console.log("Done");
});
myAsyncFunc();
Обратите внимание на то, что оба эти решения носят асинхронный характер. Это означает, что myAsyncFunc (в обоих случаях) вернется во время сна.
Важно отметить, что этот вопрос отличается от того, что такое JavaScript-версия sleep ()? где инициатор запроса запрашивает настоящий сон (отсутствие выполнения другого кода в процессе), а не задержку между действиями.
let co = gen => (...args) => { let iter = gen(...args); let resume = () => new Promise((resolve, reject) => { let result = iter.next(); if (result.done) resolve(result.value); else Promise.resolve(result.value).then(resume).then(resolve, reject); }); return resume(); };
позволит вам let asyncAdd = co(function* (a, b) { console.log('Sleeping'); yield sleep(3000); console.log('Done'); return a + b; }); asyncAdd(3, 4).then(console.log);
использовать определение sleep()
из вашего второго блока кода.
Если вам нужны менее неуклюжие функции, чем setTimeout
и setInterval
, вы можете заключить их в функции, которые просто меняют порядок аргументов и дают им красивые имена:
function after(ms, fn){ setTimeout(fn, ms); }
function every(ms, fn){ setInterval(fn, ms); }
Версии CoffeeScript:
after = (ms, fn)-> setTimeout fn, ms
every = (ms, fn)-> setInterval fn, ms
Затем вы можете использовать их с анонимными функциями:
after(1000, function(){
console.log("it's been a second");
after(1000, function(){
console.log("it's been another second");
});
});
Теперь он легко читается как «через N миллисекунд, ...» (или «каждые N миллисекунд, ...»)
Другой способ сделать это - использовать Promise и setTimeout (обратите внимание, что вам нужно находиться внутри функции и установить ее как асинхронную с ключевым словом async):
async yourAsynchronousFunction () {
var a = 1+3;
await new Promise( (resolve) => {
setTimeout( () => { resolve(); }, 3000);
}
var b = a + 4;
}
Вот очень простой способ сделать это, который «ощущается» как синхронный сон / пауза, но является допустимым асинхронным кодом js.
// Create a simple pause function
const pause = (timeoutMsec) => new Promise(resolve => setTimeout(resolve,timeoutMsec))
async function main () {
console.log('starting');
// Call with await to pause. Note that the main function is declared asyc
await pause(3*1000)
console.log('done');
}
Вы можете использовать простой javascript, это вызовет вашу функцию / метод через 5 секунд:
setTimeout(()=> { your_function(); }, 5000);
Есть несколько способов решить эту проблему. Если мы используем setTimeout
функцию, давайте сначала познакомимся с ней.
Эта функция имеет три параметра: function
или code
, delay
(в миллисекундах) и parameters
. Поскольку параметр функции или кода является обязательным, остальные необязательны. Если вы не вошли в задержку , она будет установлена на ноль.
Для получения более подробной информации setTimeout()
перейдите по этой ссылке .
Упрощенная версия:
var a = 1 + 3;
var b;
console.log('a = ' + a);
setTimeout(function(){
b = a + 4;
console.log('b = ' + b);
}, 1000);
output:
a = 4
24 -> Номер-идентификатор списка активных таймаутов
b = 8
Используя передачу параметров:
var a = 1 + 3;
var b;
console.log('a = ' + a);
setTimeout(myFunction, 1000, a);
function myFunction(a)
{
var b = a + 4;
console.log('b = ' + b);
}
вывод:
a = 4
25 -> Номер-идентификатор списка активных таймаутов
b = 8
Поддержка браузера:
Chrome Firefox Edge Safari Opera 1,0 1,0 4,0 1,0 4,0
Это моя модель, которая показывает, как «засыпать» или «DoEvents» в javascript с помощью функции генератора (ES6). Прокомментированный код:
<html>
<head>
<script>
"use strict"; // always
// Based on post by www-0av-Com /programming/3143928
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
var divelt, time0, globaln = 0; // global variables
var MainGenObj = Main(); // generator object = generator function()
window.onload = function() {
divelt = document.getElementsByTagName("body")[0]; // for addline()
addline("typeof Main: " + typeof Main);
addline("typeof MainDriver: " + typeof MainDriver);
addline("typeof MainGenObj: " + typeof MainGenObj);
time0 = new Date().valueOf(); // starting time ms
MainDriver(); // do all parts of Main()
}
function* Main() { // this is "Main" -- generator function -- code goes here
// could be loops, or inline, like this:
addline("Part A, time: " + time() + ", " + ++globaln); // part A
yield 2000; // yield for 2000 ms (like sleep)
addline("Part B, time: " + time() + ", " + ++globaln); // part B
yield 3000; // yield for 3000 ms (or like DoEvents)
addline("Part Z, time: " + time() + ", " + ++globaln); // part Z (last part)
addline("End, time: " + time());
}
function MainDriver() { // this does all parts, with delays
var obj = MainGenObj.next(); // executes the next (or first) part of Main()
if (obj.done == false) { // if "yield"ed, this will be false
setTimeout(MainDriver, obj.value); // repeat after delay
}
}
function time() { // seconds from time0 to 3 decimal places
var ret = ((new Date().valueOf() - time0)/1000).toString();
if (ret.indexOf(".") == -1) ret += ".000";
while (ret.indexOf(".") >= ret.length-3) ret += "0";
return ret;
}
function addline(what) { // output
divelt.innerHTML += "<br />\n" + what;
}
</script>
</head>
<body>
<button onclick="alert('I\'m alive!');"> Hit me to see if I'm alive </button>
</body>
</html>
Попробуйте эту функцию:
const delay = (ms, cb) => setTimeout(cb, ms)
Вот как вы его используете:
console.log("Waiting for 5 seconds.")
delay(5000, function() {
console.log("Finished waiting for 5 seconds.")
})
Или используйте стиль обещания:
const delay = ms => new Promise(resolve => {
setTimeout(resolve, ms)
})
Вот демо .