Реализовать отмену регистрации после регистрации обратного вызова - PullRequest
0 голосов
/ 30 октября 2019

Я написал простое программное обеспечение, которое позволяет пользователям «регистрировать» функцию, когда установлено состояние. Это было легко достигнуто путем добавления функций в массив. Я хочу вернуть функцию, которая способна «отменить регистрацию» этой конкретной функции. Обратите внимание, что пользователь может зарегистрировать одну и ту же функцию дважды. Это означает, что функция «отмены регистрации» не может основываться на функции в качестве ключа на карте

Единственное, что приходит на ум, - это сделать функцию «регистрация» более сложной, где каждый элемент в «Массив callbacks - это не просто функция, а такой объект:

{
  id: someId
  fn: [the function]
}

И эта функция отменяет регистрацию значения someId. Но мне просто не нравится это.

Идеи?

const state = {}
const callbacks = []

const register = (fn) => {
  callbacks.push(fn)
  return () => {
    console.log('Unregister function. HELP!!! How do I do this?')
  }
}

const setState = async (key, value) => {
  state[key] = value
  for (const fn of callbacks) fn(key, value)
}

const getState = (key) => {
  return state[key]
}

const f1 = () => {
  console.log('f1')
}

const f2 = () => {
  console.log('f2')
}

const unregF1a = register(f1)
const unrefF1b = register(f1)
const unregF2 = register(f2)
setState('some', 'a')
unregF1a()
setState('some', 'b')

1 Ответ

1 голос
/ 30 октября 2019

Переберите ваши обратные вызовы и удалите нужную функцию (работает, если одна и та же функция зарегистрирована дважды). Вы можете сделать простой цикл for:

function unregister(fn) {
  for (let i = callbacks.length - 1; i >= 0; i--) {
    if (callbacks[i] === fn) {
      callbacks.splice(i, 1)
    }
  }
}

Или вы можете использовать let и заменить весь массив:

let callbacks = [];

function unregister(fn) {
  callbacks = callbacks.filter(cb => cb !== fn)
}

Если вы хотите иметь возможность зарегистрироватьсяодна и та же функция более одного раза и сможет отменить их независимую регистрацию, тогда да, вам нужно отследить какой-то идентификатор.

Идентификатор может быть чем-то простым, например, увеличивающимся целым числом, и вы можете сохранитьони в другом массиве, в том же индексе функция находится в массиве обратных вызовов (это хэширование).

Примерно так:

const state = {}
const callbacks = []
const ids = []

let nextId = 0

const register = (fn) => {
  const id = nextId

  callbacks.push(fn)
  ids.push(nextId)
  nextId++

  return () => {
    // find the function position using the ids array:
    const fnIndex = ids.findIndex(cbId => cbId === id)

    if (fnIndex === -1) return // or throw something

    // Now remove the element from both arrays:
    callbacks.splice(fnIndex, 1)
    ids.splice(fnIndex, 1)
  }
}

Таким образом, функция отмены регистрации всегда ищетточный индекс, в котором находится id / fn.

...