Неработающая временная задержка Javascript [дубликат]

<?
 foreach($csmap_data as $key => $csm)
 {
  $csmap_data[$key]['flag'] = 1;
 }

Это должно сделать трюк.

1557
задан 12 revs, 10 users 38% 17 March 2018 в 19:15
поделиться

30 ответов

Обновление 2017

С 2009 года, когда задавался этот вопрос, JavaScript значительно изменился. Все остальные ответы теперь устарели или слишком сложны. Вот текущая лучшая практика:

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function demo() {
  console.log('Taking a break...');
  await sleep(2000);
  console.log('Two second later');
}

demo();

Вот и все. await sleep(<duration>).

Вы можете попробовать этот код live в Runkit . Обратите внимание, что

  1. await может выполняться только в функциях с префиксом ключевого слова async. Runkit завершает ваш код в асинхронной функции перед его исполнением.
  2. await останавливает только текущую функцию async

. Две новые функции JavaScript помогли написать этот фактический " сон ":

Совместимость

Если по какой-то причине вы используете Node старше 7 или ориентированы на старые браузеры, async / await все еще можно использовать через Babel (инструмент, который будет транслировать JavaScript + новые функции в простой старый JavaScript), с transform-async-to-generator плагин . Запустите

npm install babel-cli --save

Создайте .babelrc с помощью:

{
  "plugins": [
    "transform-async-to-generator",
  ]
}

Затем запустите свой код с помощью

node_modules/babel-cli/bin/babel-node.js sleep.js

Но вам опять не нужно это, если вы используете Node 7 или более позднюю версию, или если вы ориентируетесь на современные браузеры.

1104
ответ дан mplungjan 16 August 2018 в 02:02
поделиться
  • 1
    Отличный материал здесь. Интересно, как это влияет или связано с современными браузерами "active & quot; / "неактивный" состояния после того, как JS вызывает «спать», Режим? Может ли браузер блокировать сон, как ожидалось, для общего JS, чтобы потом вспомнить, когда становится «активным», или у него другое поведение? – Andre Canilho 12 October 2016 в 02:16
  • 2
    Какова текущая поддержка браузера для этого? Я бы не рассматривал предыдущие решения как «устаревшие». пока это решение не будет поддержано подавляющим большинством браузеров или, по крайней мере, всеми распространенными. Напротив, я бы счел это решение интересным, но непригодным / нецелесообразным до тех пор, пока оно не получило широкой поддержки. – Alvin Thompson 27 December 2016 в 18:56
  • 3
    @AlvinThompson: большинство современных веб-разработок используют transpilers, поэтому поддержка встроенного браузера имеет меньшее значение, чем более чистый и более надежный код. Во всяком случае, см. caniuse . – Dan Dascalescu 8 January 2017 в 11:31
  • 4
    Это не «настоящий сон». и не отвечает на вопрос. Человек, который попросил, четко дал понять stackoverflow.com/questions/758688/sleep-in-javascript и его вопрос. В реальном сне никакой другой код не может быть выполнен (если только в другом потоке). Этот ответ хорош для другого вопроса. – niry 11 January 2017 в 18:00
  • 5
    @jacroe - транспилятор обрабатывает функции стрелок, а также async / await (что может привести к тому, что IE все равно будет рвать кровь) – Jaromanda X 30 May 2017 в 08:39

Многие ответы не отвечают (напрямую) на вопрос, и он тоже ...

Вот мои два цента (или функции):

Если вы хотите меньше clunky функций, чем 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 миллисекунд», . ")

5
ответ дан 2 revs 16 August 2018 в 02:02
поделиться

Вот простое решение с использованием синхронного XMLHttpRequest:

function sleep(n){
  var request = new XMLHttpRequest();
  request.open('GET', '/sleep.php?n=' + n, false);  // `false` makes the request synchronous
  request.send(null);
}

содержимого sleep.php:

<?php sleep($_GET['n']);

Теперь вызовите его с помощью sleep (5);

270
ответ дан 2 revs, 2 users 96% 16 August 2018 в 02:02
поделиться
  • 1
    Я предполагаю, что это шутка ... +1! – lukad 17 November 2014 в 14:51
  • 2
    @lukad, используйте setTimeout(), если это работает, но если это значит, что разгадать 1000 строк обратных вызовов, это может показаться не похожим на шутки. – pguardiario 25 December 2014 в 02:01
  • 3
    Это не ответ. Это точно так же, как и код в вопросе, но немного короче. – jab 2 June 2015 в 04:23
  • 4
    Уникальный подход, хотя, к сожалению, неасинхронные XMLHttpRequests устарели и будут удалены в будущем. Что смешно, потому что именно это и привело меня к этому вопросу в первую очередь. – Beejor 14 June 2015 в 20:30
  • 5
    это БУДЕТ работать. :-) – hanshenrik 13 March 2016 в 02:42
  • 6
    На самом деле это довольно хорошая идея ИМО. Хотя я не думаю, что API сна (URL-адрес запроса) должен быть общедоступным, поскольку его можно злоупотреблять. – Vahid Amiri 12 May 2016 в 13:18
  • 7
    Занят ожидание, правда? В JS? За секунды? Если я поймаю сайт, сделавший это, он будет заблокирован. – mafu 19 August 2016 в 12:27
  • 8
    @mafu Вот почему он говорит only for debug/dev ... rolleyes – xDaizu 29 August 2016 в 10:31
  • 9
    @mafu, это правда, так сложно найти подходящий пример, который, вероятно, заслуживает собственного вопроса! – xDaizu 30 August 2016 в 08:25
  • 10
    НИКОГДА НЕ ДЕЛАЙТЕ ЭТО. Это заставит процессор ударить 100% на ядре, которое он выполнит и заблокирует. – noego 18 December 2017 в 11:51
  • 11
    – Nabi K.A.Z. 9 June 2018 в 04:07

Большинство ответов здесь ошибочны или, по крайней мере, устарели. Нет никакой причины, по которой javascript должен быть однопоточным, и действительно, это не так. Сегодня все основные браузеры поддерживают работников, прежде чем это было так, как и другие java-скрипты, такие как Rhino и Node.js, поддерживающие многопоточность.

«Javascript is single threaded» недействительный ответ. Например, запуск функции сна внутри рабочего не будет блокировать какой-либо из кода, выполняющегося в потоке ui.

В более поздних версиях, поддерживающих генераторы и производительность, можно было бы использовать аналогичную функциональность для функции sleep в одном поточном environment:

// This is based on the latest ES6 drafts.
// js 1.7+ (SpiderMonkey/Firefox 2+) syntax is slightly different

// run code you want to sleep here (ommit star if using js 1.7)
function* main(){
    for (var i = 0; i < 10; i++) {
        // to sleep for 10 milliseconds 10 times in a row
        yield 10;
    }

    yield 5;
    console.log('I just slept 5 milliseconds!');
}

// resume the given generator after ms milliseconds
function resume(ms, generator){
    setTimeout(function(){
        // ommit .value if using js 1.7
        var nextSleep = generator.next().value;
        resume(nextSleep, generator);
    }, ms);
}

// initialize generator and get first sleep for recursive function
var
    generator = main(),
    firstSleep = generator.next().value;

// initialize recursive resume function
resume(firstSleep, generator);

Эта имитация сна отличается от истинной функции сна, поскольку она не блокирует поток. Это просто сахара поверх текущей функции setTimeout javascript. Этот тип функциональности был реализован в Task.js и должен работать сегодня в Firefox.

8
ответ дан 3 revs, 2 users 90% 16 August 2018 в 02:02
поделиться
  • 1
    Рабочие не реализованы в IE, по крайней мере, через версию 10. В настоящее время это большое количество пользователей. – Beejor 14 June 2015 в 20:44
  • 2
    Правда, и даже тогда нецелесообразно реализовать sleep с использованием нескольких работников. Если использование функций генератора Node.js уже реализовано и может быть использовано, как описано. В настоящее время браузеры не все используют генераторы на сегодняшний день. – Gabriel Ratener 4 September 2015 в 15:07

Я тоже искал решение для сна (не для производственного кода, только для dev / tests) и нашел эту статью:

http://narayanraman.blogspot.com/2005/ 12 / javascript-sleep-or-wait.html

... и вот еще одна ссылка с клиентскими решениями: http://www.devcheater.com/

Кроме того, когда вы вызываете alert(), ваш код также будет приостановлен, пока отображается предупреждение - нужно найти способ не отображать предупреждение, но получить тот же эффект. :)

42
ответ дан 4 revs, 3 users 46% 16 August 2018 в 02:02
поделиться
  • 1
    Я согласен, много людей говорят: «Нет, не делай этого в производственном коде!» Да, я не хочу. Я хочу сделать это в тестовом тестовом коде, и в результате я не хочу тратить много времени на элегантное решение. – user435779 17 October 2012 в 16:03
  • 2
    Хотя эта ссылка может ответить на вопрос, лучше включить здесь основные части ответа и предоставить ссылку для справки. Ответные ссылки могут стать недействительными, если связанная страница изменится. - Из обзора – Adelin 20 July 2018 в 10:23

(См. обновленный ответ за 2016 год )

Я думаю, что вполне разумно хотеть выполнить действие, подождать, а затем выполнить другое действие. Если вы привыкли писать на многопоточных языках, у вас, вероятно, есть идея уступить выполнение на определенное количество времени, пока ваш поток не проснется.

Проблема в том, что JavaScript является однопоточным основанной на событиях. Хотя в конкретном случае было бы неплохо заставить весь двигатель ждать несколько секунд, в общем, это плохая практика. Предположим, я хотел использовать ваши функции при написании собственных? Когда я позвоню вашему методу, мои методы все замерзнут. Если JavaScript каким-то образом сохранит контекст выполнения вашей функции, сохраните его где-нибудь, затем верните его и продолжите позже, тогда может произойти сон, но это будет в основном потоком.

Таким образом, вы сильно зацикливаетесь на том, что другие предложили - вам нужно разбить код на несколько функций.

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

830
ответ дан 4 revs, 3 users 67% 16 August 2018 в 02:02
поделиться
  • 1
    Это не правильный ответ. Если Javascript не имеет функции сна, это происходит только потому, что ECMAScript этого не требует. Это выбор дизайна для органа, отвечающего за дизайн Javascript. Можно было бы предположить, что время выполнения Javascript ждет определенное количество времени перед запуском следующей строки кода, но оно было выбрано не для. – Didier A. 16 August 2013 в 20:20
  • 2
    Сон вполне может быть реализован в JavaScript, но не в режиме реального времени. В конце концов, это система, основанная на событиях. Если асинхронные вызовы завершены, инициируется событие. Я не вижу причин, по которым то же самое невозможно сделать, когда выдается sleep (), после которого элемент управления возвращается браузеру до тех пор, пока спящий не будет закончен, возвращая управление вызывающей функции. И да, я также согласен с тем, что иногда спать удобно, особенно когда разработчики до того, как вы так плохо придумали дизайн, что у вас нет другого выхода, кроме полного рефакторинга, для которого у вас нет времени – Lawrence 14 November 2013 в 14:40
  • 3
    Попробуйте Hypnotic, который следует этой идее: coolwanglu.github.io/hypnotic/web/demo.html – Tezcat 5 December 2013 в 12:34
  • 4
    Вызов javascript one-threaded - это лишь миф. Хотя это может быть технически правильно, функционально он действует как многопоточный langauge. Имитация fork () тривиально проста, и хотя yield () на самом деле не реализуется, вы можете приблизиться, используя разделяемую память для блокировки / семафора. Для среднего программиста имеет смысл рассматривать его как многопоточное; техническое имя имеет значение только для разработчиков языка. – Benubird 29 January 2015 в 16:06
  • 5
    Я согласен, почему sleep() невозможно в JS, и что большую часть времени есть лучшие способы делать что-то. Но я все же считаю, что двигатель все связывает, чтобы быть дефектом дизайна; нет никакой причины, чтобы язык не мог иметь функцию sleep(), ограниченную конкретным сценарием, страницей или функцией, без того, чтобы движок блокировал процессор и замораживал приложение, как маньяк. Это 2015 год, и вы не сможете повредить весь веб-браузер с помощью while(1). У нас есть Flash для подобных вещей. – Beejor 12 September 2015 в 05:10

Старый вопрос с 2009 года. Теперь в 2015 году возможно новое решение с генераторами, определенными в ECMAscript 2015, а также ES6. Он был одобрен в июне, но раньше он был реализован в Firefox и Chrome. Теперь функция сна может быть сделана не занятой, неблокирующей и вложенной внутренней петлей и подфункций без замораживания браузера. Требуется только чистый JavaScript, нет библиотек или фреймворков.

В приведенной ниже программе показано, как сделать sleep() и runSleepyTask(). Функция sleep() - это только оператор yield. Это так просто, что на самом деле легче написать оператор yield непосредственно вместо вызова sleep(), но тогда не будет слова сна :-). Результат возвращает значение времени для метода next() внутри wakeup() и ждет. Фактический «спящий» выполняется в wakeup(), используя старый добрый setTimeout(). При обратном вызове метод next() запускает оператор yield для продолжения, а «магия» доходности заключается в том, что все локальные переменные и весь стек вызовов вокруг него все еще остаются нетронутыми.

Функции которые используют sleep () или yield должны быть определены как генераторы. Легко сделать, добавив звездочку к ключевому слову function*. Выполнять генератор немного сложнее. При вызове с ключевым словом new генератор возвращает объект, который имеет метод next(), но тело генератора не выполняется (ключевое слово new является необязательным и не имеет значения). Метод next() запускает выполнение тела генератора до тех пор, пока он не встретит yield. Функция обертки runSleepyTask() запускает пинг-понг: next() ждет yield, а yield ждет next().

Другой способ вызвать генератор - с ключевым словом yield*, здесь он работает как простой вызов функции, но также включает способность возвращаться к next().

Все это демонстрируется примером drawTree(). Он рисует дерево с листьями на вращающейся 3D-сцене. Дерево рисуется как ствол с тремя частями вверху в разных направлениях. Затем каждая часть рисуется как другое, но меньшее дерево, вызывая drawTree() рекурсивно после короткого сна. Очень маленькое дерево рисуется как только лист.

Каждый лист имеет свою собственную жизнь в отдельной задаче, начатой ​​с runSleepyTask(). Он рождается, растет, сидит, исчезает, падает и умирает growLeaf(). Скорость регулируется с помощью sleep(). Это демонстрирует, как легко выполнить многозадачность.

function* sleep(milliseconds) {yield milliseconds};

function runSleepyTask(task) {
    (function wakeup() {
        var result = task.next();
        if (!result.done) setTimeout(wakeup, result.value);
    })()
}
//////////////// written by Ole Middelboe  /////////////////////////////

pen3D =setup3D();
var taskObject = new drawTree(pen3D.center, 5);
runSleepyTask(taskObject);

function* drawTree(root3D, size) {
    if (size < 2) runSleepyTask(new growLeaf(root3D))
    else {
        pen3D.drawTrunk(root3D, size);
        for (var p of [1, 3, 5]) {
            var part3D = new pen3D.Thing;
            root3D.add(part3D);
            part3D.move(size).turn(p).tilt(1-p/20);
            yield* sleep(50);
            yield* drawTree(part3D, (0.7+p/40)*size);
        }
    }
}

function* growLeaf(stem3D) {
    var leaf3D = pen3D.drawLeaf(stem3D);
    for (var s=0;s++<15;) {yield* sleep(100); leaf3D.scale.multiplyScalar(1.1)}
    yield* sleep( 1000 + 9000*Math.random() );
    for (var c=0;c++<30;) {yield* sleep(200); leaf3D.skin.color.setRGB(c/30, 1-c/40, 0)}
    for (var m=0;m++<90;) {yield* sleep( 50); leaf3D.turn(0.4).tilt(0.3).move(2)}
    leaf3D.visible = false;
}
///////////////////////////////////////////////////////////////////////

function setup3D() {
    var scene, camera, renderer, diretionalLight, pen3D;

    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(75, 
        window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.set(0, 15, 20);
    renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    
    directionalLight = new THREE.DirectionalLight(0xffffaa, 0.7);
    directionalLight.position.set(-1, 2, 1);
    scene.add(directionalLight);
    scene.add(new THREE.AmbientLight(0x9999ff));
      
    (function render() {
        requestAnimationFrame(render);
        // renderer.setSize( window.innerWidth, window.innerHeight );
        scene.rotateY(10/60/60);
        renderer.render(scene, camera);
    })();
    
    window.addEventListener(
        'resize',
        function(){
            renderer.setSize( window.innerWidth, window.innerHeight );
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
       }, 
       false
    );
    
    pen3D = {
        drawTrunk: function(root, size) {
            // root.skin = skin(0.5, 0.3, 0.2);
            root.add(new THREE.Mesh(new THREE.CylinderGeometry(size/12, size/10, size, 16), 
                root.skin).translateY(size/2));
            root.add(new THREE.Mesh(new THREE.SphereGeometry(size/12, 16), 
                root.skin).translateY(size));
            return root;
        },
        
        drawLeaf: function(stem) {
            stem.skin.color.setRGB(0, 1, 0);
            stem.add(new THREE.Mesh(new THREE.CylinderGeometry(0, 0.02, 0.6), 
                stem.skin) .rotateX(0.3).translateY(0.3));
            stem.add(new THREE.Mesh(new THREE.CircleGeometry(0.2), 
                stem.skin) .rotateX(0.3).translateY(0.4));
            return stem;
        },
        
        Thing: function() {
            THREE.Object3D.call(this);
            this.skin = new THREE.MeshLambertMaterial({
                color: new THREE.Color(0.5, 0.3, 0.2),
                vertexColors: THREE.FaceColors,
                side: THREE.DoubleSide
            })
        }
    };

    pen3D.Thing.prototype = Object.create(THREE.Object3D.prototype);
    pen3D.Thing.prototype.tilt = pen3D.Thing.prototype.rotateX;
    pen3D.Thing.prototype.turn = pen3D.Thing.prototype.rotateY;
    pen3D.Thing.prototype.move = pen3D.Thing.prototype.translateY;
    
    pen3D.center = new pen3D.Thing;
    scene.add(pen3D.center);
    
    return pen3D;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>

3D-материал скрыт внутри setup3D () и включен только в сделать его менее скучным, чем console.log ().

Проверено на работу в Firefox и Chrome. Не реализовано в Internet Explore и iOS (iPads). Попробуйте запустить его самостоятельно.

После очередного ответа, который я нашел, Габриэль Ратенер сделал аналогичный ответ год назад: https://stackoverflow.com/a/24401317/5032384

4
ответ дан 5 revs 16 August 2018 в 02:02
поделиться

Для любви к $ DEITY, пожалуйста, не выполняйте функцию ожидания ожидания ожидания. setTimeout и setInterval делают все, что вам нужно.

113
ответ дан 5 revs, 2 users 83% 16 August 2018 в 02:02
поделиться
  • 1
    Согласен. Не будет реального «сна». заморозить весь движок javascript ... – Skurmedel 4 June 2009 в 15:46
  • 2
    Ну не совсем все: setInterval делает гораздо лучшее впечатление от опроса. – annakata 4 June 2009 в 15:48
  • 3
    Что бы этот фрагмент кода not задерживался в движке JavaScript? – Deniz Dogan 4 June 2009 в 15:51
  • 4
    Если вам не нужен синхронный сон, в этом случае это вполне действительный вопрос. – Aaron Dufour 21 September 2011 в 17:54
  • 5
    Я думаю, многие из нас могут забыть, что JavaScript не является языком только для браузера. Этот чувак мог бы создать утилиту командной строки узла, для которой требуется короткая пауза, без необходимости обрабатывать все проблемы, связанные с переменной, которые поставляются с setTimeout. – Phil LaNasa 2 March 2014 в 14:07

В JavaScript я переписываю каждую функцию так, чтобы она могла завершиться как можно скорее. Вы хотите, чтобы браузер вернулся в управление, чтобы он мог внести изменения в DOM.

Каждый раз, когда мне хотелось поспать в середине моей функции, я реорганизовал использовать setTimeout().

Я собираюсь отредактировать этот ответ, потому что нашел это полезным:

Беспокойный сон, или задержка, функционирует на любом языке, много обсуждается. Некоторые скажут, что всегда должен быть сигнал или обратный вызов для запуска данной функции, другие будут утверждать, что иногда произвольный момент задержки полезен. Я говорю, что каждому свое и одно правило никогда не может диктовать что-либо в этой отрасли.

Написание функции сна просто и делает его еще более полезным с помощью JavaScript Promises:

// sleep time expects milliseconds
function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

// Usage!
sleep(500).then(() => {
    // Do something after the sleep!
});
590
ответ дан 5 revs, 5 users 32% 16 August 2018 в 02:02
поделиться
  • 1
    В порядке закрытия. function foobar(el) { setTimeout(function() { foobar_cont(el); }, 5000); } – chaos 8 April 2010 в 04:27
  • 2
    нормально, и что, если код не предназначен для использования на веб-странице? – Eugenio Miró 22 July 2010 в 16:23
  • 3
    @ EugenioMiró, если код не предназначен для использования на веб-странице, объектная модель хоста реализует метод сна. - Я думаю, что вопрос направлен на DOM, который подвергается javascript, запущенному на веб-страницах. – BrainSlugs83 24 September 2011 в 01:57
  • 4
    @Nosredna да, мы понимаем, как делать асинхронные вызовы, это не помогает нам спать (). Я хочу, чтобы мои звонки выполнялись в определенном порядке, и чтобы данные возвращались в определенном порядке. У меня 5 уровней в петле for. Я хочу выполнить BLOCK. Истинный метод сна не будет «замедлять работу браузера», управление спиной сна обратно в браузер и любые другие потоки, требующие процессорного времени, пока он все еще блокируется. – BrainSlugs83 24 September 2011 в 01:59
  • 5
    это не ответ на вопрос. – TMS 24 November 2011 в 15:22

Один сценарий, в котором вам может понадобиться функция sleep (), а не с помощью setTimeout (), - это если у вас есть функция, реагирующая на щелчок пользователя, который в конечном итоге откроет новое всплывающее окно, и вы инициировали некоторую обработку, которая требует короткий период для заполнения до появления всплывающего окна. Перемещение открытого окна в закрытие означает, что он обычно блокируется браузером.

5
ответ дан acuth 16 August 2018 в 02:02
поделиться

Мне лично нравится простой:

function sleep(seconds){
    var waitUntil = new Date().getTime() + seconds*1000;
    while(new Date().getTime() < waitUntil) true;
}

then:

sleep(2); // Sleeps for 2 seconds

Я все время использую его для создания времени поддельной загрузки при создании скриптов в P5js

15
ответ дан Akelian 16 August 2018 в 02:02
поделиться
  • 1
    Я рассматриваю это как наиболее оптимизированную версию основного вопроса: он не делает никаких математических вычислений внутри цикла, просто сравним. Это немного сложно читать. – hegez 27 October 2017 в 16:45
  • 2
    НИКОГДА НИКОГДА НЕ ДЕЛАЙТЕ ЭТО. Вы проверяли использование ЦП, пока эта функция работает? Он должен быть близок к 100%, если вы дадите ему достаточно времени. – noego 18 December 2017 в 11:46
  • 3
    Это ожидание ... – Andreas L. 30 May 2018 в 07:08

Если вы используете jQuery, кто-то действительно создал плагин «delay», который является не чем иным, как оболочкой для setTimeout:

// Delay Plugin for jQuery
// - http://www.evanbot.com
// - © 2008 Evan Byrne

jQuery.fn.delay = function(time,func){
    this.each(function(){
        setTimeout(func,time);
    });

    return this;
};

Затем вы можете просто использовать его в строке вызовов функций как ожидается:

$('#warning')
.addClass('highlight')
.delay(1000)
.removeClass('highlight');
65
ответ дан Alan Plum 16 August 2018 в 02:02
поделиться
  • 1
    Это не плохое решение. Сохраняет контекст и целостность. – Nosredna 10 June 2009 в 20:00
  • 2
    Начиная с jQuery 1.4, .delay() является частью jQuery (хотя семантика отличается от вышеприведенной реализации). api.jquery.com/delay – Matt Ball 24 October 2011 в 14:26
  • 3
    На этот вопрос определенно отсутствовал ответ jQuery . Так рад, что получилось! – xDaizu 30 August 2016 в 08:56
  • 4
    Если вам нужна задержка между двумя независимыми вызовами, да. Если вам нужны задержки для замедления цикла, нет. – WGroleau 31 May 2018 в 21:43

Вы не можете спать, как в JavaScript, или, скорее, не должны. Запуск цикла sleep или while заставит браузер пользователя висеть до тех пор, пока цикл не будет выполнен.

Используйте таймер, как указано в ссылке, на которую вы ссылаетесь.

4
ответ дан Andrew Dunkman 16 August 2018 в 02:02
поделиться

В конкретном случае, когда вы хотите освободить набор вызовов, выполняемых циклом, вы можете использовать что-то вроде кода ниже с прототипом. Без прототипа вы можете заменить функцию задержки на setTimeout.

function itemHandler(item)
{
    alert(item);
}

var itemSet = ['a','b','c'];

// Each call to itemHandler will execute
// 1 second apart
for(var i=0; i<itemSet.length; i++)
{
    var secondsUntilExecution = i;
    itemHandler.delay(secondsUntilExecution, item)
}
4
ответ дан beauburrier 16 August 2018 в 02:02
поделиться

Если вы правильно выполняете функцию сна, например

var sleep = function(period, decision, callback){
    var interval = setInterval(function(){
        if (decision()) {
            interval = clearInterval(interval);
            callback();
        }
    }, period);
}

, и у вас есть асинхронная функция для вызова несколько раз

var xhr = function(url, callback){
    // make ajax request
    // call callback when request fulfills
}

И вы настраиваете свой проект следующим образом:

var ready = false;

function xhr1(){
    xhr(url1, function(){ ready = true;});  
}
function xhr2(){
    xhr(url2, function(){ ready = true; }); 
}
function xhr3(){
    xhr(url3, function(){ ready = true; }); 
}

Тогда вы можете сделать это:

xhr1();
sleep(100, function(){ return done; }, xhr2);
sleep(100, function(){ return done; }, xhr3);
sleep(100, function(){ return done; }, function(){
    // do more
});

Вместо бесконечного отступного обратного вызова:

xhr(url1, function(){
    xhr2(url2, function(){
        xhr3(url3, function(){
            // do more
        });
    });
});
3
ответ дан BishopZ 16 August 2018 в 02:02
поделиться

Добавление двух моих битов. Мне нужно было ожидание для тестирования. Я не хотел разрывать код, так как это было бы большой работой, поэтому для меня это было просто.

for (var i=0;i<1000000;i++){                    
     //waiting
  }

Я не вижу недостатков в этом, и это помогло мне.

5
ответ дан caiocpricci2 16 August 2018 в 02:02
поделиться
  • 1
    Это может быть скомпилировано. – Viktor Sehr 19 July 2013 в 21:22
  • 2
    Пожалуйста, не делайте этого так. Это блокировка блокировки , что означает, что никакой другой javascript не может запускаться, пока ваш код запутывает поток JS. – Steve Midgley 22 October 2014 в 05:47
  • 3
    @SteveMidgley & quot; никакой другой javascript [возможность] не запускать, пока ваш код вызывает зависание потока JS & quot; мне кажется, именно то, что OP хочет сделать ¯_ (ツ) _ / ¯ – drigoangelo 10 March 2015 в 23:39
  • 4
    Я просто запускал несколько тестов, и кажется, что даже пустой цикл блокирует браузер и процессор (а не только JavaScript). И использование циклов for будет почти всегда выполняться немедленно, независимо от максимального значения для i, и даже с помощью сложного математического кода, помещенного внутри. Поэтому, если вы не ждали всего несколько миллисекунд, все еще, похоже, не умеет спокойно спать в JS. – Beejor 14 June 2015 в 22:03
  • 5
    1 миллион слишком велик. Для меня достаточно 10 тыс. – V. Kalyuzhnyu 30 January 2018 в 15:22

Я согласен с другими плакатами, занятый сон - это просто плохая идея.

Однако setTimeout не останавливает выполнение, он выполняет следующую строку функции сразу после таймаута SET, а не после истечения таймаута, так что не выполняет ту же задачу, что и сон.

Способ сделать это - разбивать вашу функцию на до и после частей.

function doStuff()
{
  //do some things
  setTimeout(continueExecution, 10000) //wait ten seconds before continuing
}

function continueExecution()
{
   //finish doing things after the pause
}

Убедитесь, что имена ваших функций по-прежнему точно описывают, что делает каждая часть (IE GatherInputThenWait и CheckInput, а не funcPart1 и funcPart2)

Изменить

Этот метод достигает цели не выполнять строки кода, которые вы решаете, до ПОСЛЕ вашего таймаута, все еще возвращая управление обратно на клиентский ПК, чтобы выполнить все, что он поставил в очередь.

Дальнейшее редактирование

Как указано в комментариях, это абсолютно НЕ РАБОТАЕТ в цикле. Вы могли бы сделать какой-то причудливый (уродливый) взлом, чтобы заставить его работать в цикле, но в целом это будет просто для катастрофического кода спагетти.

164
ответ дан DevinB 16 August 2018 в 02:02
поделиться
  • 1
    Да. Там, где это сложно, когда у вас есть петля или даже вложенная петля. Вы должны отказаться от своих циклов и иметь счетчики вместо этого. – Nosredna 4 June 2009 в 16:10
  • 2
    Туш. Я имею в виду, что это было бы возможно, но уродливое и хакерское в этом случае. Вы также можете использовать некоторые статические логические переменные состояния, но это также довольно хаки. – DevinB 4 June 2009 в 16:20
  • 3
    -1 для этого. Опять же, это не отвечает на вопрос. Это скорее ответ на вопрос типа «Как выполнить функцию асинхронно», который сильно отличается от «Как заблокировать выполнение кода». – Deepak G M 28 January 2013 в 10:32
  • 4
    @Nosredna Нет, вы бы использовали закрытие. Например: function foo(index) { setTimeout(function() { foo_continue(index); }, 10000); } и for(var X = 0; X < 3;X++) { foo(X); } - значение значение для X передается в foo, которое затем повторно используется под именем index, когда foo_continue в конечном итоге вызывается. – Izkata 13 January 2014 в 21:34
  • 5
    @Alexander Конечно, это так, потому что точка setTimeout () заключается в том, чтобы предотвратить блокировку браузера, выполнив код асинхронно. Поместите console.log() внутри foo_continue() в версии setTimeout и получите тот же результат. – Izkata 23 March 2015 в 15:20

Я хотел бы инкапсулировать setTimeOut в согласованности с обещаниями для других асинхронных задач: Демо в Fiddle

function sleep(ms)
{
    return(new Promise(function(resolve, reject) {        
        setTimeout(function() { resolve(); }, ms);        
    }));    
}

Используется как:

sleep(2000).then(function() { 
   // Do something
});

Легко запомнить синтаксис, если вы использовали Promises.

9
ответ дан Elo 16 August 2018 в 02:02
поделиться
  • 1
    Почему это лучше, чем просто использовать setTimeout (function () {/ * do something * /}, 2000) ;? – JSideris 9 March 2016 в 11:15

Для браузеров я согласен с тем, что setTimeout и setInterval - это путь.

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

Если вы используете node.js и meteor, вы можете столкнуться с ограничениями использования setTimeout в волокне. Вот код для сна на стороне сервера.

var Fiber = require('fibers');

function sleep(ms) {
    var fiber = Fiber.current;
    setTimeout(function() {
        fiber.run();
    }, ms);
    Fiber.yield();
}

Fiber(function() {
    console.log('wait... ' + new Date);
    sleep(1000);
    console.log('ok... ' + new Date);
}).run();
console.log('back in main');

Смотрите: https://github.com/laverdet/node-fibers#sleep

8
ответ дан Homer6 16 August 2018 в 02:02
поделиться

Здесь вы идете. Как говорится в коде, не плохой разработчик и используйте это на сайтах. Это функция полезности для разработки.

// Basic sleep function based on ms.
// DO NOT USE ON PUBLIC FACING WEBSITES.
function sleep(ms) {
    var unixtime_ms = new Date().getTime();
    while(new Date().getTime() < unixtime_ms + ms) {}
}
28
ответ дан Ian Maddox 16 August 2018 в 02:02
поделиться
  • 1
    Это в основном то же самое, что и у ОП. – Andrew Barber 3 November 2012 в 04:16
  • 2
    Чтобы быть более точным, это то, что ОП попросил ALTERNATIVE. – WGroleau 25 May 2018 в 20:48
  • 3
    Решение не очень хорошо, но в некоторых местах async/await оно не реагирует, к сожалению, и мы должны использовать его мандатно. – Nabi K.A.Z. 9 June 2018 в 04:06

Лучшее решение для того, чтобы все выглядело так, как хочет большинство людей, - это использовать анонимную функцию:

alert('start');
var a = 'foo';
//lots of code
setTimeout(function(){  //Beginning of code that should run AFTER the timeout
    alert(a);
    //lots more code
},5000);  // put the timeout here

Это, вероятно, самое близкое к тому, что вы просто делаете, что хотите.

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

12
ответ дан Mainguy 16 August 2018 в 02:02
поделиться

Я знаю, что это немного старый вопрос, но если (как и я) вы используете Javascript с Rhino, вы можете использовать ...

try
{
  java.lang.Thread.sleep(timeInMilliseconds);
}
catch (e)
{
  /*
   * This will happen if the sleep is woken up - you might want to check
   * if enough time has passed and sleep again if not - depending on how
   * important the sleep time is to you.
   */
}
109
ответ дан mjaggard 16 August 2018 в 02:02
поделиться

Я могу понять цель функции сна, если вам приходится иметь дело с синхронным исполнением. Функции setInterval и setTimeout создают поток параллельного выполнения, который возвращает последовательность выполнения обратно в основную программу, что неэффективно, если вам нужно ждать определенного результата. Конечно, можно использовать события и обработчики, но в некоторых случаях это не то, что предназначено.

6
ответ дан naazgull 16 August 2018 в 02:02
поделиться

Прежде всего - setTimeout и setInterval - это то, что должно использоваться, из-за обратного вызова javascript. Если вы хотите использовать sleep(), это неправильный поток управления или архитектура вашего кода.

Сказав, что, я полагаю, я все еще могу помочь с двумя реализациями сна.

  1. faking синхронный запуск с верхней части моей головы:
    //a module to do taht //dual-license: MIT or WTF [you can use it anyhow and leave my nickname in a comment if you want to]
    var _=(function(){
     var queue=[];
     var play=function(){
       var go=queue.shift();
         if(go){if(go.a){go.f();play();}else{setTimeout(play,go.t);}}
       }
     return {
       go:function(f){
        queue.push({a:1,f:f});
        },
       sleep:function(t){
        queue.push({a:0,t:t});
        },
       playback:play 
     }
    })();
    
    [сделать автоматическое воспроизведение также возможно]
    //usage
    
    _.go(function(){
    
    //your code
    console.log('first');
    
    });
    
    
    _.sleep(5000);
    
    _.go(function(){
    
    //your code
    console.log('next');
    
    });
    
    //this triggers the simulation
    _.playback();
    
  2. реальный синхронный запуск

Я много думал об этом однажды, и единственная идея, которую я имел для истинного сна в javascript, является технической.

функция сна должна быть синхронным вызовом AJAX с тайм-аутом, установленным для сна стоимость. Это все и единственный способ иметь реальный sleep()

3
ответ дан naugtur 16 August 2018 в 02:02
поделиться

Сначала:

Определите функцию, которую вы хотите выполнить следующим образом:

function alertWorld(){
  alert("Hello World");
}

Затем планируйте свое выполнение с помощью метода setTimeout:

setTimeout(alertWorld,1000)

Обратите внимание на две вещи

  • , второй аргумент - время в miliseconds
  • в качестве первого аргумента, вам нужно передать только имя (ссылку) функции без скобок
15
ответ дан Pablo Fernandez 16 August 2018 в 02:02
поделиться

Это можно сделать с помощью метода сна Java. Я тестировал его в FF и IE, и он не блокирует компьютер, не переваривает ресурсы и не вызывает бесконечные удары сервера. Кажется, это чистое решение для меня.

Сначала вам нужно загрузить Java на страницу и сделать ее методы доступными. Для этого я сделал следующее:

<html>
<head>

<script type="text/javascript">

  function load() {
    var appletRef = document.getElementById("app");
    window.java = appletRef.Packages.java;
  } // endfunction

</script>

<body onLoad="load()">

<embed id="app" code="java.applet.Applet" type="application/x-java-applet" MAYSCRIPT="true" width="0" height="0" />

Затем все, что вам нужно сделать, когда вы хотите, чтобы безболезненная пауза в вашем JS была:

java.lang.Thread.sleep(xxx)

Где xxx - время в миллисекундах. В моем случае (в порядке обоснования) это было частью выполнения резервного копирования в очень маленькой компании, и мне нужно было распечатать счет, который должен был быть загружен с сервера. Я сделал это, загрузив счет-фактуру (как веб-страницу) в iFrame, а затем распечатав iFrame. Конечно, мне пришлось ждать, пока страница будет полностью загружена, прежде чем я смогу напечатать, поэтому JS пришлось приостановить. Я выполнил это, указав на странице счета (в iFrame) поле скрытой формы на родительской странице с событием onLoad. И код на родительской странице для печати счета-фактуры выглядел следующим образом (нерелевантные части, вырезанные для ясности):

var isReady = eval('document.batchForm.ready');
isReady.value=0;

frames['rpc_frame'].location.href=url;

while (isReady.value==0) {
  java.lang.Thread.sleep(250);
} // endwhile

window.frames['rpc_frame'].focus();
window.frames['rpc_frame'].print();

Таким образом, пользователь нажимает кнопку, скрипт загружает страницу счета-фактуры, а затем ждет, проверяя через каждые четверть секунды, чтобы посмотреть, завершена ли страница счета-фактуры, затем отобразите диалоговое окно печати, чтобы пользователь мог отправить его на принтер. КЭД.

5
ответ дан Rachael 16 August 2018 в 02:02
поделиться
  • 1
    Кажется, совершенно чудовищная душевность при рассмотрении простой вещи, которую хотел достичь автор. – xaralis 22 January 2013 в 18:17
  • 2
    Это зависит от Java-апплетов, которые устарели. – Vahid Amiri 12 May 2016 в 13:22
function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}
7
ответ дан Shemeer M Ali 16 August 2018 в 02:02
поделиться
  • 1
    Это то же самое, что и реальный вопрос. Не так много смысла, что это реальный ответ. – EML 12 June 2014 в 20:16
  • 2
    Нехорошее решение - использование этого в Selenium's JavaScriptExecutor зависело от моего браузера Chrome примерно в 50% случаев на 2104 MacBook Pro. – emery 6 May 2015 в 17:33

Если вы находитесь на узле.js, вы можете взглянуть на волокна - родное расширение C на узел, своеобразное многопоточное моделирование.

It позволяет сделать реальный sleep таким образом, который блокирует выполнение в волокне, но он не блокируется в основном потоке и других волокнах.

Вот пример из собственного readme:

// sleep.js

var Fiber = require('fibers');

function sleep(ms) {
    var fiber = Fiber.current;
    setTimeout(function() {
        fiber.run();
    }, ms);
    Fiber.yield();
}

Fiber(function() {
    console.log('wait... ' + new Date);
    sleep(1000);
    console.log('ok... ' + new Date);
}).run();
console.log('back in main');

- и результаты:

$ node sleep.js
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
4
ответ дан tomekwi 16 August 2018 в 02:02
поделиться

Я искал / googled несколько веб-страниц в javascript sleep / wait ... и нет ответа, если вы хотите, чтобы javascript «RUN, DELAY, RUN» ... то, что большинство людей получили, было либо: «RUN, RUN (бесполезный материал), RUN "или" RUN, RUN + delayed RUN "....

Итак, я съел некоторые гамбургеры и подумал ::: вот решение, которое работает ... но вы нужно рубить ваши коды ... ::: да, я знаю, это просто легче читать рефакторинг ... все еще ...

// ........ ................................. // example1:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setInterval
var i = 0;

function run() {
    //pieces of codes to run
    if (i==0){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i==1){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i==2){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i >2){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i==5){document.getElementById("id1").innerHTML= "<p>all code segment finished running</p>"; clearInterval(t); } //end interval, stops run
    i++; //segment of code finished running, next...
}

run();
t=setInterval("run()",1000);

</script>
</body>
</html>

//. ................................... // пример2:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setTimeout
var i = 0;

function run() {
    //pieces of codes to run, can use switch statement
    if (i==0){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>"; sleep(1000);}
    if (i==1){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>"; sleep(2000);}
    if (i==2){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>"; sleep(3000);}
    if (i==3){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>";} //stops automatically
    i++;
}

function sleep(dur) {t=setTimeout("run()",dur);} //starts flow control again after dur

run(); //starts
</script>
</body>
</html>

/ / ................. example3:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setTimeout
var i = 0;

function flow() {
    run(i);
    i++; //code segment finished running, increment i; can put elsewhere
    sleep(1000);
    if (i==5) {clearTimeout(t);} //stops flow, must be after sleep()
}

function run(segment) {
    //pieces of codes to run, can use switch statement
    if (segment==0){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==1){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment >2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
}

function sleep(dur) {t=setTimeout("flow()",dur);} //starts flow control again after dur

flow(); //starts flow
</script>
</body>
</html>

// .............. example4:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setTimeout, switch
var i = 0;

function flow() {
    switch(i)
    {
        case 0:
            run(i);
            sleep(1000);
            break;
        case 1:
            run(i);
            sleep(2000);
            break;
        case 5:
            run(i);
            clearTimeout(t); //stops flow
            break;
        default:
            run(i);
            sleep(3000);
            break;
    }
}

function run(segment) {
    //pieces of codes to run, can use switch statement
    if (segment==0){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==1){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment >2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    i++; //current segment of code finished running, next...
}

function sleep(dur) {t=setTimeout("flow()",dur);} //starts flow control again after dur

flow(); //starts flow control for first time...
</script>
</body>
</html>
7
ответ дан user207408 16 August 2018 в 02:02
поделиться
  • 1
    Хорошо, это работает с setTimeput, но трудно понять, что происходит. Использование самого setTimeout проще, чем это. – naugtur 9 August 2011 в 09:19

Только для debug / dev я публикую это, если он кому-то полезен

Интересные вещи, в Firebug (и, возможно, другие консоли js), ничего не происходит после входа в игру, только после того, как указанная продолжительность сна (...)

function sleepFor( sleepDuration ){
    var now = new Date().getTime();
    while(new Date().getTime() < now + sleepDuration){ /* do nothing */ } 
}

Пример использования:

function sleepThenAct(){ sleepFor(2000); console.log("hello js sleep !"); }
270
ответ дан 2 revs, 2 users 96% 16 August 2018 в 02:02
поделиться
  • 1
    Это не ответ. Это точно так же, как и код в вопросе, но немного короче. – jab 2 June 2015 в 04:23
  • 2
    Занят ожидание, правда? В JS? За секунды? Если я поймаю сайт, сделавший это, он будет заблокирован. – mafu 19 August 2016 в 12:27
  • 3
    @mafu Вот почему он говорит only for debug/dev ... rolleyes – xDaizu 29 August 2016 в 10:31
  • 4
    @mafu, это правда, так сложно найти подходящий пример, который, вероятно, заслуживает собственного вопроса! – xDaizu 30 August 2016 в 08:25
  • 5
    НИКОГДА НЕ ДЕЛАЙТЕ ЭТО. Это заставит процессор ударить 100% на ядре, которое он выполнит и заблокирует. – noego 18 December 2017 в 11:51
Другие вопросы по тегам:

Похожие вопросы: