Как я могу отслеживать позицию обратного вызова в массиве, чтобы я мог запустить следующий?
Мое требование состоит в том, что это должно быть совместимо с ES5.
Учитывая гипотетический массив обратных вызовов, мне нужно выяснить, в каком индексе он находится. Проблема в том, что один и тот же обратный вызов может дублироваться.
Использование порядкового номера неоптимально, так как обратные вызовы могут вызываться несколько раз с разной скоростью.
По сути, я ищу способ следовать по пути независимо от того, когда и сколько раз был вызван обратный вызов.
Пример:
let callbacks = [CB1, CB2, CB3, CB1, CB3, CB2]
Если вызывается CB3, я ожидаю, что он перейдет к следующему в списке, а не назад (т.е. по пути вставки).
Пример:
CB3 -> CB1 -> CB3 -> CB2
Следует отметить, что CB3 отвечает ТОЛЬКО за вызов CB1, а CB1 отвечает за вызов следующего в списке.
Лучший пример:
CB3 -> CB1
CB1 -> CB3 (2)
CB3 (2) -> CB2
Если CB3 является вторым в списке, он не должен следовать по тому же пути, что и первый CB3 в списке.
Пример:
CB3 (2) -> CB2
Другой джентльмен заметил, что это напоминает ему промежуточное ПО Express, и я сказал, что оно действительно очень похоже.
Я сделал, я хочу следовать заданному пути обратных вызовов в том порядке, в котором они вызываются. Как я могу быть более ясным? Отредактировано, чтобы уточнить важное предложение.
Что вы подразумеваете под "следить"?
Для перехода к следующему в списке. Я не предполагал, что «следование пути» было неясным для большинства.
Тогда почему бы не сохранить индекс в глобальной переменной?
Из-за того, что обратные вызовы вызываются несколько раз не по порядку. Я объяснил это в разделе «неоптимальный».
Потому что я не могу контролировать выполнение каждого обратного вызова. Это должно быть сделано самими обратными вызовами.
Похоже на случай проблема XY
К сожалению, я потерял веру в то, что большинство разработчиков действительно помогают мне решать проблемы, а не пытаются сказать мне, что я делаю это неправильно. Я ДЕЙСТВИТЕЛЬНО не знаю, как я могу более эффективно объяснить свои проблемы с более высоким обзором. ЭТО решение, которое мне нужно, и мне нужна помощь без объяснения всей логики моего приложения.
можете добавить пример, что вы хотите получить, если вызывается первая CB3?
CB3 -> CB1 -> CB3 -> CB2. По сути переходим к следующему по списку.
Это чем-то напоминает мне экспресс-промежуточное ПО, где у каждого промежуточного ПО есть параметр next для вызова следующего промежуточного ПО. Но я не понимаю проблемы/решения.
Очень хороший момент. Это очень похоже на промежуточное ПО Express.



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


Если одно и то же значение может появляться несколько раз, то нет реального способа отследить, где в массиве вы находитесь, без использования индекса.
Единственный другой вариант, который я могу придумать, - это клонировать массив и элементы сдвига по мере того, как вы это делали.
const a = () => console.info('a');
const b = () => console.info('b');
const c = () => console.info('c');
const callbacks = [a, a, b, a, c];
const duplicate = callbacks.concat();
while (duplicate.length) {
duplicate.shift()();
}… но я бы придерживался индекса.
Вы можете взять итерационные протоколы, реализовав Symbol.iterator в Array#[@@iterator](), и повторять его до тех пор, пока не будут доступны другие элементы.
var CB1 = () => console.info('CB1'),
CB2 = () => console.info('CB2'),
CB3 = () => console.info('CB3'),
callbacks = [CB1, CB2, CB3, CB1, CB3, CB2],
gen = callbacks[Symbol.iterator]();
interval = setInterval(function () {
var g = gen.next();
if (g.done) {
clearInterval(interval);
return;
}
g.value();
}, 1000);Отличное решение! Я забыл уточнить, что это должно быть совместимо с ES5. Хотя, возможно, я смогу сдвинуть Символ и Генераторы. В любом случае голосование.
Решил это, создав фабричную функцию и привязав обратный вызов функции.
Пример:
var CB1 = function(cb){ cb('CB1') }
var CB2 = function(cb){ cb('CB2') }
var CB3 = function(cb){ cb('CB3') }
var callbacks = [CB1, CB2, CB3, CB1, CB3, CB2]
let cbs = []
// Factory function that returns a new function
function factory(fn) {
const newFn = function newFn() { return fn.apply(this, arguments) }
return newFn
}
// Callback to pass into CB
let out = function(i, data){
console.info(i, data)
i++
if (cbs[i])
cbs[i].call(cbs[i], cbs[i].out)
}
// Loop through callbacks and create a new array with bound out functions
for (let i = 0; i < callbacks.length; i++) {
let cb = new factory(callbacks[i])
cb.out = out.bind(cb, i)
cbs.push(cb)
}
// And to demonstrate
function start(atI) {
cbs[atI].call(cbs[atI], cbs[atI].out)
}
start(3)
> 3 'CB1'
> 4 'CB3'
> 5 'CB2'
Пожалуйста, попробуйте лучше объяснить свою задачу.