Используйте замыкание для очистки функции, которая строит объект с помощью рекурсии - JavaScript - PullRequest
0 голосов
/ 05 февраля 2019

Я сделал функцию, основанную на обещаниях, которая сканирует иерархию, пока не достигнет вершины, и разрешается с помощью объекта, содержащего структуру.Моя единственная неприятность с кодом заключается в том, что я изменяю переменные вне тела функции, что означает, что это не чистая функция.Я изучил замыкания JavaScript и полностью понял их тривиальное использование.Но я изо всех сил пытаюсь выяснить, как / если они могут помочь сделать мою функцию чистой.Мои попытки сделать замыкание до сих пор только перезаписывают переменные, но не изменяют их.Вот код, о котором идет речь, с использованием глобальных переменных:

/* I want to move these variables inside function body to purify 'getPriorRows'*/
let priorRows = {}, level = 0;

const getPriorRows = id => new Promise(resolve => {
  fetch(`/api/org/${id}`).then(result => {

    /* global varaiables are modified here */
    priorRows[level++] = result;

    if (result.parentID) resolve(getPriorRows(result.parentID));
    else resolve(priorRows);

  });
});

getPriorRows('123432').then(result => console.log(result));

Любые замечания по этому вопросу приветствуются.

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Передайте значения в качестве аргументов:

function getPriorRows(id, priorRows = {}, level = 0) {
  return fetch(`/api/org/${id}`).then(result => {
    /* global varaiables are modified here */
    priorRows[level] = result;

    if (result.parentID) return getPriorRows(result.parentID, priorRows, level+1);
    else return priorRows;
  });
}

getPriorRows('123432').then(result => console.log(result));

Вы можете использовать либо параметры по умолчанию, либо функцию-обертку, вам даже не нужно замыкание:

function getAll(id) { return getPriorRows(id, {}, 0); }

Также Iудален Promise конструктор антипаттерна .

0 голосов
/ 05 февраля 2019

Вы должны иметь возможность заключить всю функцию и ее «внешние» переменные в новую функцию:

function getPriorRows(id) {

  let priorRows = {}, level = 0;
  const getNext = id => new Promise(
     ...
  );

  return getNext(id);
}

Тем не менее, ваше создание явного new Promise в каждой итерации является анти-Promise-pattern:

function getPriorRows(id) {

  let priorRows = {}, level = 0;

  const getNext = id => fetch(`/api/org/${id}`).then(result => {
    priorRows[level++] = result
    if (result.parentID) {
      return getNext(result.parentID));
    } else {
      return priorRows;
    }
  });

  return getNext(id);
}

В любом случае, преимущество переноса состояния таким образом заключается в том, что теперь вы можете иметь несколько вызовов на getPriorRows, проходящих параллельно, не мешая друг другу.

РЕДАКТИРОВАТЬ второй код, отредактированный для исправления ошибки копирования и вставки с рекурсией - вы должны рекурсивно вызывать внутреннюю функцию, а не внешнюю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...