Sleep in JavaScript-задержка между действиями



есть ли способ сделать сон в JavaScript, прежде чем он выполняет другое действие?



пример:



 var a = 1+3;
// Sleep 3 seconds before the next action here
var b = a + 4;
1290   8  

8 ответов:

можно использовать 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, используя генераторы с выходом для "блокировки кода":

потому что исходный вопрос был отправлен семь лет назад, я не потрудился ответить с точным кодом, потому что это просто слишком легко и уже ответил. Это должно помочь в более сложных задачах, например, если вам нужно по крайней мере два сна, или если вы планируете последовательность асинхронного выполнения. Не стесняйтесь изменять его под свои по необходимости.

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
)

обновить 2018

последние Safari, Firefox и узел.js теперь также поддерживают async / await / promises.

обновление 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();

использование 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();

обратите внимание на то, что оба эти решения асинхронны по своей природе. Это означает, что myAsyncFunc (в обоих случаях) вернется во время сна.

важно отметить, что этот вопрос отличается от что такое JavaScript-версия 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 миллисекунд ...")

есть несколько способов решить эту проблему. Если мы используем 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

Это моя модель, которая показывает, как" спать "или" 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>

другой способ сделать это-с помощью Promise и setTimeout (обратите внимание, что вам нужно быть внутри функции и установить ее как асинхронную с ключевым словом async):

async yourAsynchronousFunction () {

    var a = 1+3;

    await new Promise( (resolve, reject) => {
        setTimeout( () => { resolve(true); }, 3000);
    }

    var b = a + 4;

}

Comments

    Ничего не найдено.