代码之家  ›  专栏  ›  技术社区  ›  Audun Olsen

使用闭包来净化通过递归JavaScript构建对象的函数

  •  1
  • Audun Olsen  · 技术社区  · 7 年前

    我制作了一个基于承诺的函数,它沿着层次结构向上爬行,直到到达顶部,并与包含该结构的对象进行解析。我对代码的唯一不满是我修改了函数体之外的变量,这意味着它不是一个纯函数。我已经研究了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 回复  |  直到 7 年前
        1
  •  3
  •   Bergi    7 年前

    将值作为参数传递:

    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 constructor antipattern .

        2
  •  3
  •   Alnitak    7 年前

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

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

    也就是说,你创造了一个明确的 new 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 并行进行而不相互干扰。

    编辑

    推荐文章