Страницы

Поиск по вопросам

Показаны сообщения с ярлыком settimeout. Показать все сообщения
Показаны сообщения с ярлыком settimeout. Показать все сообщения

пятница, 14 февраля 2020 г.

setTimeout внутри setInterval, не получается установить интервал setTimeout

#setinterval #settimeout


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

Но время присутствия не поддается регулированию, а, такое впечатление, что зависит
от времени всего интервала t

var t = setInterval(function appear(){
    var ghost = document.getElementById("ghost");
    if (ghost.style.display == "none")
            {ghost.style.display = "block";}
    else
            {var t1 = setTimeout(function disappear(){
            ghost.style.display = "none";
            }, 1)}      
}, 6000)


Исчезнуть оно должно по функции t1. Хочется сделать еще меньше. Задержка t1 урезана
до 1 мс, но никакой реакции. Отчего это?



var t = setInterval(function appear() {
  var ghost = document.getElementById("ghost");
  if (ghost.style.display == "none") {
    ghost.style.display = "block";
  } else {
    var t1 = setTimeout(function disappear() {
      ghost.style.display = "none";
    }, 1)
  }
}, 6000)
body {
  background: black url(https://s.cdpn.io/16327/texture_bg.jpg) no-repeat 50% 0px;
}

#ghost {
  position: absolute;
  left: 25%;
  display: none;
}




    


Ответы

Ответ 1



Проблема Вашего кода в том, что ожидание disappear вы пишете в ветке else. Это значит, что у этой ветки нет шансов выполниться на текущей итерации setInterval. Чтобы контроллировать время исчезновения, нужно выставлять setTimeout непосредственно после отображения. Вторая проблема в проверке: ghost.style.display == "none" Это не работает для стилей, полученных через каскадные таблицы (т.е. если стиль указан не для самого элемента, а каким-то образом в css). Можно либо вручную инициализировать стиль элемента, либо использовать getComputedStyle чтобы получить актуальные стили элемента после применения css. var ghost = document.getElementById("ghost"); ghost.style.display = "none"; var t = setInterval(function appear() { if (ghost.style.display == "none") { ghost.style.display = "block"; // Просто убираем else setTimeout(function () { ghost.style.display = "none"; }, 300) } }, 3000) body { background: black url(https://s.cdpn.io/16327/texture_bg.jpg) no-repeat 50% 0px; } #ghost { position: absolute; left: 25%; display: none; }

Ответ 2



Так Вы можете менять промежутки времени видимой/невидимой картинки, изменяя значения переменных showSeconds и hideSeconds. var hideSeconds = 3; var showSeconds = 1; function switchGhost(show) { var ghost = document.getElementById("ghost"); if (show) { ghost.style.display = "block"; setTimeout(switchGhost, showSeconds * 1000, !show); } else { ghost.style.display = "none"; setTimeout(switchGhost, hideSeconds * 1000, !show); } } switchGhost(false); body { background: black url(https://s.cdpn.io/16327/texture_bg.jpg) no-repeat 50% 0px; } #ghost { position: absolute; left: 25%; display: none; }

среда, 1 января 2020 г.

Повторение кода через разные промежутки времени Javascript

#javascript #setinterval #settimeout


Здравствуйте. 
Мне нужно реализовать следующую логику:  
  1 этап: пользователи что-то делают на сервере - 40 секунд  
  2 этап: выполняется процесс - случайное кол-во секунд (от 3 до 10)  
  3 этап: кулдаун - пользователи любуются результатом - 2 секунды  
и все повторяется с начала и так вечно

setInterval не подходит, так как в нем код повторяется через РАВНЫЕ промежутки времени,
а время окончания работы моего кода становится известно только в процессе. Если же
использовать время интервала с запасом, то 3 этап будет выполняться то 2 секунды, то
15 - неприемлемо.

Такое решение (рекурсия)



function round() {
    var delay = 20000 * Math.random(); //узнаем, через сколько в этот раз должен
сработать код
    setTimeout(function () {

        console.log('Hellow world!');//что-то тут делаю
        round(); //и перезапускаю

    }, delay);
}

round();




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

явно ведь должно быть красивое и правильное решение? что в таком случае использовать?
Нужно сделать так, чтобы была какая-то асинхронная функция с примерно таким содержанием:

-сообщить о начале 1 этапа (использую socket.io)  
-ждать 40 секунд  
-сообщить о начале 2 этапа  
-ждать случайное кол-во секунд  
-сообщить о начале третьего  
-ждать 2 секунды

потом функция должна запуститься заново но не рекурсией. И хотелось бы без вложенных
друг в друга setTimeout. И не подобным "Войне и Миру" кодом.
    


Ответы

Ответ 1



Вложеные setTimeout стек не забивают, так как выполняются асинхронно, их бояться не надо. Для решения вашей ситуации вам надо написать самому какую-то timing микро библиотеку, позволяющую создавать цепи событий с таймаутами. Это что-то типа промисов в fetch. Выглядеть этот код будет примерно так TimeoutChain.PlusOne(() => { /*...*/ },2000) .PlusOne(() => { /* ещё код*/ },3000).StartChain(); Реализация будет на основе setTimeout. Но это будет выглядеть красиво, так как она инкапсулирована в эту функцию, так же из-за её асинхронности стек она не будет забивать. Так как каждая функция вызывает свой setTimeout а сама завершается. Тут в примере пауза явно задаётся в цепи, но можно её значение просто например возвращать из самой лямбды.

Ответ 2



Как вариант - написать js функцию, которая в конце будет вызывать саму себя с setTimeout

mousemove event JS

#javascript #settimeout #mouse_event


Помогите пожалуйста, не лезет в голову как реализовать. Когда пользователь не двигает
 мышкой несколько секунд на div`е, нужно чтобы вызывалось событие при спокойствии мыши.
Проще говоря, мне нужен антоним на mousemove.
    


Ответы

Ответ 1



var meBlock = document.getElementById('me-block'), t; meBlock.addEventListener('mousemove', function(e) { meBlock.style.backgroundColor = 'green'; meBlock.style.color = "#fff"; meBlock.innerHTML = 'МЫША БЕГАЕТ'; clearTimeout(t); t = setTimeout(function() { meBlock.style.backgroundColor = 'red'; meBlock.innerHTML = 'МЫША СТАЛ'; }, 1000); }); meBlock.addEventListener('mouseout', function(e) { meBlock.style.backgroundColor = 'transparent'; meBlock.style.color = "#000"; meBlock.innerHTML = 'МЫША НЕТЬ'; clearTimeout(t); }) #me-block { width: 200px; height: 100px; border: 1px solid #000; }


вторник, 31 декабря 2019 г.

Значение this при вызове функции через setTimeout

#javascript #settimeout #this




function f() {
  'use strict';
  alert(this);
}
f(); // выводится undefined
setTimeout(f, 0); // выводится [object Window]




Т. е. при вызове функции через setTimeout игнорируется 'use strict'. Почему?
    


Ответы

Ответ 1



данное поведение документировано: Проблема с "this" Когда вы передаете метод в setTimeout() (или любую другую функцию), то он будет выполнен со значением this, которое может отличаться от того, которое вы ожидаете. Более подробно эта проблема объясняется в руководстве. Объяснение Код, исполняемый в setTimeout(), имеет другой контекст выполнения, нежели функция, вызвавшая setTimeout. Для установки значения this вызываемой функции применяются обычные правила, и если вы не установили значение this при вызове или, используя bind, то значением по умолчанию в non-strict режиме будет объект global (или window), а в strict-режиме значение undefined. Оно не будет таким же как значение this функции, вызвавшей setTimeout. Замечание: Значение this по умолчанию в callback-методе, вызванном в setTimeout, все равно будет иметь значение window, а не undefined, даже при использовании strict mode.

Ответ 2



В дополнение к ответу @teran таймеры: setTimeout, setInterval, setImmediate не являются частью спецификации ECMA, а предоставляются окружением. Из-за этого их поведение, в том числе для определения this может отличаться в зависимости от того, где запускается код, например: браузер - window nodejs - объект таймера.

Ответ 3



Передайте в функцию нужный вам this var ob = { name: 'Name Object', count: 1 }; function f() { 'use strict'; alert(this.name); } setTimeout(f.bind(ob), 0);

вторник, 24 декабря 2019 г.

Почему не увеличивается длительность исполнения функции?

#settimeout #javascript #замыкания #циклы #функции


for (j=1;j<=5;j ++)
{
    (function(i){
        setTimeout(function(){console.log(i)}, j*500)
    })(j)
}

Интересует конкретно данный кусок кода, почему задержка не увеличивается на 500 мс?
Был бы благодарен если кто нибудь описал принцип работы функции.    


Ответы

Ответ 1



Вы по сути одновременно запускаете пять функций, т.е. ваш код идентичен: (function(i){setTimeout(function(){console.log(i)}, 1*500)})(1) (function(i){setTimeout(function(){console.log(i)}, 2*500)})(2) (function(i){setTimeout(function(){console.log(i)}, 3*500)})(3) (function(i){setTimeout(function(){console.log(i)}, 4*500)})(4) (function(i){setTimeout(function(){console.log(i)}, 5*500)})(5) Что приводит к эффекту вывода пяти сообщений в консоль с интервалом 500 миллисекунд.

вторник, 16 апреля 2019 г.

Значение this при вызове функции через setTimeout

function f() { 'use strict'; alert(this); } f(); // выводится undefined setTimeout(f, 0); // выводится [object Window]
Т. е. при вызове функции через setTimeout игнорируется 'use strict'. Почему?


Ответ

данное поведение документировано
Проблема с "this" Когда вы передаете метод в setTimeout() (или любую другую функцию), то он будет выполнен со значением this, которое может отличаться от того, которое вы ожидаете. Более подробно эта проблема объясняется в руководстве. Объяснение Код, исполняемый в setTimeout(), имеет другой контекст выполнения, нежели функция, вызвавшая setTimeout. Для установки значения this вызываемой функции применяются обычные правила, и если вы не установили значение this при вызове или, используя bind, то значением по умолчанию в non-strict режиме будет объект global (или window), а в strict-режиме значение undefined. Оно не будет таким же как значение this функции, вызвавшей setTimeout Замечание: Значение this по умолчанию в callback-методе, вызванном в setTimeout, все равно будет иметь значение window, а не undefined, даже при использовании strict mode

среда, 9 января 2019 г.

Повторение кода через разные промежутки времени Javascript

Здравствуйте. Мне нужно реализовать следующую логику: 1 этап: пользователи что-то делают на сервере - 40 секунд 2 этап: выполняется процесс - случайное кол-во секунд (от 3 до 10) 3 этап: кулдаун - пользователи любуются результатом - 2 секунды и все повторяется с начала и так вечно
setInterval не подходит, так как в нем код повторяется через РАВНЫЕ промежутки времени, а время окончания работы моего кода становится известно только в процессе. Если же использовать время интервала с запасом, то 3 этап будет выполняться то 2 секунды, то 15 - неприемлемо.
Такое решение (рекурсия)
function round() { var delay = 20000 * Math.random(); //узнаем, через сколько в этот раз должен сработать код setTimeout(function () { console.log('Hellow world!');//что-то тут делаю round(); //и перезапускаю }, delay); } round();
не подойдет, так как при каждой новой рекурсии будут накапливаться временные переменные и будет забиваться память, а перезагружать сервер постоянно не получится
явно ведь должно быть красивое и правильное решение? что в таком случае использовать? Нужно сделать так, чтобы была какая-то асинхронная функция с примерно таким содержанием:
-сообщить о начале 1 этапа (использую socket.io) -ждать 40 секунд -сообщить о начале 2 этапа -ждать случайное кол-во секунд -сообщить о начале третьего -ждать 2 секунды
потом функция должна запуститься заново но не рекурсией. И хотелось бы без вложенных друг в друга setTimeout. И не подобным "Войне и Миру" кодом.


Ответ

Вложеные setTimeout стек не забивают, так как выполняются асинхронно, их бояться не надо.
Для решения вашей ситуации вам надо написать самому какую-то timing микро библиотеку, позволяющую создавать цепи событий с таймаутами. Это что-то типа промисов в fetch.
Выглядеть этот код будет примерно так
TimeoutChain.PlusOne(() => { /*...*/ },2000) .PlusOne(() => { /* ещё код*/ },3000).StartChain();
Реализация будет на основе setTimeout. Но это будет выглядеть красиво, так как она инкапсулирована в эту функцию, так же из-за её асинхронности стек она не будет забивать. Так как каждая функция вызывает свой setTimeout а сама завершается.
Тут в примере пауза явно задаётся в цепи, но можно её значение просто например возвращать из самой лямбды.