如何跟踪回调在数组中的位置,以便我可以触发下一个?
我的要求是这需要具备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中间件,我说它确实非常相似。
您可以通过在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);
如果相同的值可以多次出现,那么没有真正的方法可以在不使用索引的情况下跟踪数组中的位置。
我能想到的唯一另一个选择是在你去的时候克隆数组和移位元素。
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()();
}
...但我坚持使用索引。
通过创建工厂函数并绑定函数的回调解决了这个问题。
例:
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'