Сон в JavaScript - задержка между действиями
Есть ли способ, которым я могу заснуть в JavaScript до того, как он выполнит другое действие?
Пример:
var a = 1+3;
// Sleep 3 seconds before the next action here
var b = a + 4;
Ответы
Ответ 1
Вы можете использовать setTimeout
для достижения аналогичного эффекта:
var a = 1 + 3;
var b;
setTimeout(function() {
b = a + 4;
}, (3 * 1000));
Это на самом деле не "спящий" JavaScript - он просто выполняет функцию, переданную в setTimeout
через определенную продолжительность (указанную в миллисекундах). Хотя можно написать функцию сна для JavaScript, лучше использовать setTimeout
, если это возможно, поскольку это не затормозит все в период сна.
Ответ 2
Если вам действительно нужно sleep()
просто проверить что-то. Но имейте в виду, что это приведет к сбою браузера в большинстве случаев при отладке - возможно, именно поэтому вам это нужно. В режиме производства я прокомментирую эту функцию.
function pauseBrowser(millis) {
var date = Date.now();
var curDate = null;
do {
curDate = Date.now();
} while (curDate-date < millis);
}
Не используйте new Date()
в цикле, если вы не хотите тратить память, вычислительную мощность, аккумулятор и, возможно, срок службы вашего устройства.
Ответ 3
Версия 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()
Ответ 4
2018 Обновление
Последние Safari, Firefox и Node.js теперь также поддерживают асинхронные/ожидающие/обещания.
Обновление 2017
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();
Ответ 5
Если вам нужны менее громоздкие функции, чем 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 been a second");
after(1000, function(){
console.log("it been another second");
});
});
Теперь он легко читается как "после N миллисекунд,..." (или "каждые N миллисекунд,..." )
Ответ 6
Другой способ сделать это - использовать Promise и setTimeout (обратите внимание, что вам нужно быть внутри функции и установить ее как асинхронную с ключевым словом async):
async yourAsynchronousFunction () {
var a = 1+3;
await new Promise( (resolve) => {
setTimeout( () => { resolve(); }, 3000);
}
var b = a + 4;
}
Ответ 7
Существует несколько способов решения этой проблемы. Если мы используем функцию 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);
Выход:
a = 4
24 → Идентификатор номера списка активных тайм-аутов
b = 8
Использование параметра pass:
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
Ответ 8
Это моя модель, которая показывает, как "спать" или "DoEvents" в JavaScript, используя функцию генератора (ES6). Код комментария:
<html>
<head>
<script>
"use strict"; // always
// Based on post by www-0av-Com https://stackoverflow.com/questions/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>
Ответ 9
Попробуйте эту функцию:
function delay(ms, cb) { setTimeout(cb, ms) }
Если вы используете Babel:
const delay = (ms, cb) => setTimeout(cb, ms)
Вот как вы используете это:
console.log("Waiting for 5 seconds.")
delay(5000, function() {
console.log("Finished waiting for 5 seconds.")
})
Здесь демо.