Массив обратных вызовов, поиск позиции - PullRequest
1 голос
/ 13 марта 2019

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

Мое требование заключается в том, что он должен поддерживать 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, и я сказал, что оно действительно очень похоже.

Ответы [ 3 ]

1 голос
/ 13 марта 2019

Вы можете взять итерационные протоколы , внедрив Symbol.iterator в Array#[@@iterator](), и выполнять итерацию до тех пор, пока не будут доступны другие элементы.

var CB1 = () => console.log('CB1'),
    CB2 = () => console.log('CB2'),
    CB3 = () => console.log('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);
0 голосов
/ 13 марта 2019

Решено это путем создания фабричной функции и привязки обратного вызова функции.

Пример:

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.log(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'
0 голосов
/ 13 марта 2019

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

Единственный другой вариант, который я могу придумать, - это клонировать массив и элементы shift из него по ходу работы.

const a = () => console.log('a');
const b = () => console.log('b');
const c = () => console.log('c');

const callbacks = [a, a, b, a, c];

const duplicate = callbacks.concat();
while (duplicate.length) {
  duplicate.shift()();
}

… но я бы использовал индекс.

...