回调数组,查找位置

时间:2019-03-13 14:56:52

标签: javascript arrays callback indexof

如何跟踪数组中回调的位置,以便可以触发下一个?

我的要求是这必须具备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 个答案:

答案 0 :(得分:1)

您可以通过在iteration protocols中实现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);

答案 1 :(得分:0)

如果相同的值可以出现多次,那么就没有使用索引的真实方法来跟踪数组中的位置。

我唯一想到的另一种选择是在移动数组时克隆该数组和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()();
}

…但是我会坚持使用索引。

答案 2 :(得分:0)

通过创建工厂函数并绑定函数的回调来解决此问题。

示例:

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'