Что было бы хорошим подходом для наилучшей реализации setInterval с использованием setTimeout?
Учтите, что mocked setInterval должен иметь возможность «очищаться».
Почему ты хочешь это сделать? Какие воздержания вы формируете с помощью встроенной реализации?
потому что мне кто-то бросил вызов ради забавы. не все программы имеют реальное предназначение, и создавать вещи для чистого удовольствия - это нормально.
В таком случае вы бы приняли этот Q / A как обман? Там задача была еще веселее. Или даже Вот этот, который показывает реализацию с реальным вариантом использования.
О «реализации вашей собственной временной функции без реальной цели».
Сообщение, на которое вы ссылаетесь, не имеет прямого отношения к этому, и его нельзя получить с помощью простого запроса Google. это очень просто и оптимизировано для SEO.
Есть настоящая цель, и я не обязан вам ее рассказывать.
@JonasW. - это домашнее задание нет, посмотрите на мой счет, это, конечно, не домашнее задание или задание, а вопрос, который кто-то попросил меня помочь ему, и я погуглил и увидел, что не было никаких достойных результатов, поэтому решил внести свой вклад в Интернет с моим собственный вопрос / ответ. Я модерирую этот сайт в течение многих лет и считаю эту информацию очень интересной для других разработчиков.
Хм. Я определенно отвечал на этот вопрос более одного раза, поэтому, хотя я признаю, что это не домашнее задание, у него определенно есть дубликат, но поскольку я в настоящее время не могу его найти (поисковая система SO не самая лучшая), я отказываюсь от своего голоса и позволяю другим решить это ...



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


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 - какие характеристики? О чем ты говоришь? это работает, почему отрицательный голос?
Поскольку реализация setInterval указывается в некоторых документах, и вы не применяете эти спецификации, т.е. добавляете защиту от бесконечных циклов.
вы относитесь ко всему этому слишком серьезно. Я развлекаюсь только с javascript, языком, который я люблю и кодирую последние 13 лет.
Извините, но я совсем не вижу удовольствия в этой реализации.
Мне не нужно спрашивать вашего разрешения, чтобы задавать наводящие на размышления забавные вопросы об основах языка. Если вы не видите в этом веселья, пожалуйста, переходите к другому вопросу, сэр.
согласился с вами @vsynch
Чтобы точно издеваться над 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);
Возможно, я неправильно читаю (по телефону), но я думаю, что ваша реализация сделает невозможным очистку интервала от обратного вызова.
У меня есть решение на основе обещаний без рекурсии :)
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);