Перебор эл. массива с целью присвоения значения переменной.
Всем доброго дня! Задача такая: есть массив данных arr, мне нужно стряпать функцию, которая бесконечно (по кругу) перебирает значения каждого элемента массива через определенное время (1 сек) и присваивает это значение переменной a. При обращении она должна возвращать текущее значение переменной а.
Я новичок в JS, пробовал по разному, но не получается... Посоветовали сделать так: let a; function f(i = 0) { if (i == arr.length) i = 0; a = arr[i++]; //console.log(a); setTimeout(() => { f(i); }, 1000); } Мне нужно вместо //console.log(a); вернуть текущее значение а. Я по разному переписывал этот код, но ничего не получается. Я не пойму в чем дело? Куда нужно вставить return(a)? Или при такой конструкции не получится вернуть текущее значение? |
"...при обращении к переменной" наверное у тебя в задаче было.
И у тебя уже всё работает. Запустил функцию - она в фоне работает, в любой момент можешь в консоли написать console.log(a) и увидеть текущую a. Куда ты хочешь что return - непонятно. В общем что-то ты не так понял в задании, и сам небось не понимаешь конечного результата. |
:) :write:
<script> function fun(arr) { let time = performance.now(); Object.defineProperty(window, "a", { get: function() { let i = Math.trunc((performance.now() - time)/1000) % arr.length; return arr[i] } }); return window.a } fun([1, 2, 3, 4, 5]); window.setInterval(_ => document.body.append(`${a} `) , 1001) </script> |
Цитата:
var a; function f(i = 0) { if (i == arr.length) i = 0; a = arr[i++]; setTimeout(() => { f(i); }, 1000); } function N1() { var b; b = a + 12; return(b); } |
рони, спасибо, но я пытаюсь понять почему не работает вышеописанный пример.
|
Все разобрался, я обернул код в функцию, но ее не вызываю, соответственно a у меня вообще не генерится))
|
Все равно столкнулся с проблемой. Код генерирует a один раз, то есть переменная у меня почему-то не меняется, если я например забью ее значением массив:
var a; function f(i = 0) { if (i == arr.length) i = 0; a = arr[i++]; setTimeout(() => { f(i); }, 1000); } function N1() { let c = 0; let arr2 = []; let N = 100; for (var k = 1; k <= N; k++) { arr2.push(a); document.write('Item: ' + arr2[c++] + ' of ' + arr2.length + '<br/>'); } } У меня выдает список, в котором все 100 элементов равны одному и тому же значению переменной a. Соответственно, как я понимаю, чтобы динамически обращаться к первоначальному коду, нужно его обернуть в функцию, function N0() { var a; function f(i = 0) { if (i == arr.length) i = 0; a = arr[i++]; setTimeout(() => { f(i); }, 1000); } return(a); } function N1() { let c = 0; let arr2 = []; let N = 100; let b; for (var k = 1; k <= N; k++) { b = N0(); arr2.push(a); document.write('Item: ' + arr2[c++] + ' of ' + arr2.length + '<br/>'); } } Вообще не робит(((... |
Трудно понять чего вы хотите.
Что бы функция f начала выполняться, ее надо вызвать. Где вызов? Цикл for (var k = 1; k <= N; k++) быстренько пробежится и закончится. Он не будет ждать пока будут срабатывать все вызовы timout. Изучайте возможности асинхронного программирования в javascipt. Promise, async/await. |
Формализую задачу: необходимо создать массив, и заполнить его динамическим значением переменной a, которая с периодом в 1 сек. принимает значения элементов первоначального массива.
|
var a; async function f(i = 0) { if (i == arr.length) i = 0; a = arr[i++]; setTimeout(() => { f(i); }, 1000); } f(); function N1() { let c = 0; let arr2 = []; let N = 100; let b; for (var k = 1; k <= N; k++) { arr2.push(a); document.write('Item: ' + arr2[c++] + ' of ' + arr2.length + '<br/>'); } } Что не правильно?! |
Цитата:
|
Цитата:
const arr0 = [0,1,2,3,4]; // Исходный массив let a; // Будет каждую сек циклически получать значение следующего элемента function f(arr, i = 0) { i %= arr.length; a = arr[i]; setTimeout(() => {() => f(arr, i+1), 1000); } f(arr0); Запустили цикл с таймерами. Сначала а=0, через секунду а=1, потом а=2 и т.д. Дальше чего вы хотите? В какой момент времени вы хотите получить другой массив и чем его заполнять? Только учтите, что в javascript работающий код никто не может прервать. Пока он не завершится (например какой нибудь цикл) никакое другое событие обрабатываться не будет. Даже функция заданная в таймере. setTimeout - это не выполни функцию через заданное время (как неправильно пишут во многих учебниках). Это поставь функцию в очередь на выполнение через заданное время. А выполняться она будет, когда дойдет очередь. Если какая то задача в очереди (даже та сама, которая вызвала setTimeout будет работать слишком долго, то функция, заданная в setTimeout будет ждать. |
Цитата:
function createFunc(arr, interval) { let i = 0; setInterval(() => { i = (i + 1) % arr.length; }, interval); return () => arr[i]; } const func = createFunc([11, 22, 33, 44], 1000); ... // будет возвращать тот элемент массива, который сейчас выбран. // выбор меняется раз в секунду по кругу alert(func()); как вариант, можно добавить в функцию останавливатель и запускатель таймера, но кажется это сейчас без надобности. так же - запускать таймер при первом вызове функции, а не при создании. Это надо? |
Цитата:
Первый вариант: Мне нужно получать значение переменной через некоторое время t. Допустим через 9 сек. То есть какое значение будет принимать a каждые 9 сек. (при условии что а меняет свое значение каждую секунду). Заранее это время t не определено. То есть время через которое мне нужно снимать значение переменной а каждый раз разное. Вот значениями, которое а принимает через заданное на один сеанс запуска скрипта время t мне и нужно заполнять массив. Второй вариант: Пользователь кликает по кнопке и текущее значение а добавляется в массив. Но второй вариант не обязателен. |
uzlprog, второй вариант прост:
<input type="button" id="button" value="add a"/> <div>Выходной массив: <span id="out">[]</span></div> <script> var a; var arr = [1, 2, 3, 4, 5]; var outArr = []; function f(i = 0) { if (i == arr.length) i = 0; a = arr[i++]; setTimeout(() => { f(i); }, 1000); } f(); function add() { outArr.push(a); out.innerHTML = JSON.stringify(outArr); } button.onclick = add; </script> Первый вариант не будет иметь никакой точности. Потому что время срабатывания таймеров не может быть точным. Ты думаешь что при интервале в 1 секунду обновления а, если спрашивать каждую 9ую секунду получишь 9ое значение а? А вот и нет. Там может быть 8ое или 10ое, а может и 35ое, если ты вкладками щёлкал или запускал что-то с нагрузкой процессора. Таймер не гарантируют точное время, при установке таймера в N он сработает после N. Когда после - зависит от окружения. <input type="button" id="button" value="stop"/> <div>Выходной массив: <span id="out">[]</span></div> <script> var a; var arr = [1, 2, 3, 4, 5]; var outArr = []; function f(i = 0) { if (i == arr.length) i = 0; a = arr[i++]; setTimeout(() => { f(i); }, 1000); } f(); function add() { outArr.push(a); out.innerHTML = JSON.stringify(outArr); } function fill(t = 9) { add(); fill.timerId = setTimeout(() => { fill(t); }, t * 1000); } fill(); button.onclick = () => clearTimeout(fill.timerId); </script> |
Aetae, спасибо. С пользовательским вводом я разобрался, а вот первый вариант... Ваш код почему-то у меня выдает:
Выходной массив: [1] И все... |
Цитата:
|
Цитата:
|
Часовой пояс GMT +3, время: 06:00. |