1

我创建了一个基于 promise 的函数,它爬上一个层次结构,直到它到达顶部,并使用包含该结构的对象进行解析。我对代码的唯一抱怨是我修改了函数体之外的变量,这意味着它不是纯函数。我研究过 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));

非常感谢您对此事的任何意见。

4

2 回答 2

3

您应该能够将整个函数及其“外部”变量包含在一个新函数中:

function getPriorRows(id) {

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

  return getNext(id);
}

也就是说,您new Promise在每次迭代中创建显式是 Promise 反模式:

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并行进行,而不会相互干扰。

编辑编辑第二个代码以使用递归修复复制和粘贴错误 - 您必须递归调用内部函数,而不是外部函数。

于 2019-02-05T15:30:58.553 回答
3

将值作为参数传递:

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); }

我还删除了Promise构造函数 antipattern

于 2019-02-05T15:32:55.543 回答