Реализуйте setInterval с помощью setTimeout

Что было бы хорошим подходом для наилучшей реализации setInterval с использованием setTimeout?

Учтите, что mocked setInterval должен иметь возможность «очищаться».

stackoverflow.com/help/self-answer
vsync 03.06.2018 11:48

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

Kaiido 03.06.2018 11:51

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

vsync 03.06.2018 11:52

В таком случае вы бы приняли этот Q / A как обман? Там задача была еще веселее. Или даже Вот этот, который показывает реализацию с реальным вариантом использования.

Kaiido 03.06.2018 11:54

О «реализации вашей собственной временной функции без реальной цели».

Kaiido 03.06.2018 11:59

Сообщение, на которое вы ссылаетесь, не имеет прямого отношения к этому, и его нельзя получить с помощью простого запроса Google. это очень просто и оптимизировано для SEO.

vsync 03.06.2018 12:00

Есть настоящая цель, и я не обязан вам ее рассказывать.

vsync 03.06.2018 12:00

@JonasW. - это домашнее задание нет, посмотрите на мой счет, это, конечно, не домашнее задание или задание, а вопрос, который кто-то попросил меня помочь ему, и я погуглил и увидел, что не было никаких достойных результатов, поэтому решил внести свой вклад в Интернет с моим собственный вопрос / ответ. Я модерирую этот сайт в течение многих лет и считаю эту информацию очень интересной для других разработчиков.

vsync 03.06.2018 15:13

Хм. Я определенно отвечал на этот вопрос более одного раза, поэтому, хотя я признаю, что это не домашнее задание, у него определенно есть дубликат, но поскольку я в настоящее время не могу его найти (поисковая система SO не самая лучшая), я отказываюсь от своего голоса и позволяю другим решить это ...

Jonas Wilms 03.06.2018 20:56
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
9
2 282
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Код ниже создает фиктивную реализацию setInterval с использованием setTimeout.

function interval(cb, ms){
  var a = {
    clear : function(){
      clearTimeout(a.timer)
    }
  };
  (function run(){
    cb();
    a.timer = setTimeout(run, ms);
  })();
  
  return a;
}


var myInterval_1 = interval(()=>{ console.info(1) }, 1000); // create an "interval" 
var myInterval_2 = interval(()=>{ console.info(2) }, 1000); // create another "interval" 

// clear the first interval
setTimeout(()=>{ myInterval_1.clear() }, 4000)

Это совершенно не соответствует спецификациям.

Kaiido 03.06.2018 11:49

@Kaiido - какие характеристики? О чем ты говоришь? это работает, почему отрицательный голос?

vsync 03.06.2018 11:51

Поскольку реализация setInterval указывается в некоторых документах, и вы не применяете эти спецификации, т.е. добавляете защиту от бесконечных циклов.

Kaiido 03.06.2018 11:52

вы относитесь ко всему этому слишком серьезно. Я развлекаюсь только с javascript, языком, который я люблю и кодирую последние 13 лет.

vsync 03.06.2018 11:54

Извините, но я совсем не вижу удовольствия в этой реализации.

Kaiido 03.06.2018 11:55

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

vsync 03.06.2018 11:58

согласился с вами @vsynch

user9634982 02.08.2019 07:24

Чтобы точно издеваться над setInterval, он должен также издеваться над clearInterval:

{
  const intervals = new Map();

  function setInterval(fn, time, context, ...args) {
    const id = Math.floor(Math.random() * 10000);
    intervals.set(id, setTimeout(function next() {
       intervals.set(id, setTimeout(next, time));
       fn.apply(context, args);
    }, time));
    return id;
  }

  function clearInterval(id) { 
    clearTimeout(intervals.get(id));
  }
}

И пользоваться можно как всегда:

 const interval = setInterval(console.info, 100, console, "hi");

clearInterval(interval);

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

Kaiido 04.06.2018 01:25

У меня есть решение на основе обещаний без рекурсии :)

function setInterval1(fn, time) {
    let check = { check: true };
    (async function () {
        for (let i = 0; i < Number.POSITIVE_INFINITY && check.check; i++) {
            await new Promise((resolve) => {
                setTimeout(() => { fn(); resolve(true); }, time);
            });
        }
    })();
    return check;
}

let check = setInterval1(() => console.info('hi'), 1000);

function clearInterval1(check) {
    check.check = false;
}

setTimeout(() => { clearInterval1(check) }, 4000)

Здесь intervalId - это опорный объект, содержащий timeoutId. Ссылочный объект изменяется каждый раз, когда setTimeout вызывается рекурсивно.

const _setInterval = (callback, delay) => {
  const timerRef = { id: null };
  const timeout = () => {
    timerRef.id = setTimeout(() => {
      callback();
      timeout();
    }, delay);
  }
  timeout();
  return timerRef;
};

const timerRef = _setInterval(() => {
  console.info("Callback");
}, 1000);

setTimeout(() => {
  clearTimeout(timerRef.id);
}, 5000);

Другие вопросы по теме