Массив обратных вызовов, поиск позиции

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

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

Пожалуйста, попробуйте лучше объяснить свою задачу.

PM 77-1 13.03.2019 15:58

Я сделал, я хочу следовать заданному пути обратных вызовов в том порядке, в котором они вызываются. Как я могу быть более ясным? Отредактировано, чтобы уточнить важное предложение.

Levi Roberts 13.03.2019 15:59

Что вы подразумеваете под "следить"?

PM 77-1 13.03.2019 16:01

Для перехода к следующему в списке. Я не предполагал, что «следование пути» было неясным для большинства.

Levi Roberts 13.03.2019 16:01

Тогда почему бы не сохранить индекс в глобальной переменной?

PM 77-1 13.03.2019 16:03

Из-за того, что обратные вызовы вызываются несколько раз не по порядку. Я объяснил это в разделе «неоптимальный».

Levi Roberts 13.03.2019 16:04

Потому что я не могу контролировать выполнение каждого обратного вызова. Это должно быть сделано самими обратными вызовами.

Levi Roberts 13.03.2019 16:05

Похоже на случай проблема XY

James Coyle 13.03.2019 16:06

К сожалению, я потерял веру в то, что большинство разработчиков действительно помогают мне решать проблемы, а не пытаются сказать мне, что я делаю это неправильно. Я ДЕЙСТВИТЕЛЬНО не знаю, как я могу более эффективно объяснить свои проблемы с более высоким обзором. ЭТО решение, которое мне нужно, и мне нужна помощь без объяснения всей логики моего приложения.

Levi Roberts 13.03.2019 16:07

можете добавить пример, что вы хотите получить, если вызывается первая CB3?

Nina Scholz 13.03.2019 16:09

CB3 -> CB1 -> CB3 -> CB2. По сути переходим к следующему по списку.

Levi Roberts 13.03.2019 16:10

Это чем-то напоминает мне экспресс-промежуточное ПО, где у каждого промежуточного ПО есть параметр next для вызова следующего промежуточного ПО. Но я не понимаю проблемы/решения.

Roland Starke 13.03.2019 16:13

Очень хороший момент. Это очень похоже на промежуточное ПО Express.

Levi Roberts 13.03.2019 16:14
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
13
47
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

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

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. Хотя, возможно, я смогу сдвинуть Символ и Генераторы. В любом случае голосование.

Levi Roberts 13.03.2019 16:29
Ответ принят как подходящий

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

Пример:

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'

Другие вопросы по теме