ES6承诺的递归树步行

时间:2015-06-10 22:56:38

标签: javascript recursion binary-tree ecmascript-6 es6-promise

我正在寻找一个深度未知的对象树,并通过ES6承诺返回一个给定的节点。 (在这里使用lodash,显然没有必要,我意识到)。我已经让树行走正常了但是我有点不清楚正确的方法来确保将顶级范围变量promise传递给递归函数调用以便它可以使用它致电.resolve( data )时可用。现在它试图在一个成功的查找上执行但是由于递归函数被一个新的承诺覆盖而无法解决这个承诺而且它无法使链条冒泡:

  deepFindReturn (object, searchKey, searchVal, cb) {
    if ( !cb ) cb = _.noop;
    for(let x in object){
      if (object.hasOwnProperty(x)) {
        if ( object[searchKey] === searchVal ) {
          return cb( object );
        }
        if ( _.isArray( object[x] ) && !this.found ){
          object[x].forEach( (item) => {
            this.deepFindReturn(item, searchKey, searchVal, cb);
          });
        } else if ( typeof object[x] === typeof {}  && !this.found ) {
          this.deepFindReturn(object[x], searchKey, searchVal, cb);
        }
      }
    }
  }

  deepFindReturn(data, 'uuid', 'f8d1ffed-9b51-4982-97b7-60f8e074eda4')

这是我走路的树,如果有帮助的话:

  data = {
     "name":"root",
     "created":"2015-04-07T20:36:29.711Z",
     "createdBy":"admin",
     "uuid":"9731cedc-8ed7-4367-b95d-30898c7913a1",
     "primaryType":"folder",
     "path":"/root",
     "itemCount":7,
     "items":[
        {
           "name":"219760_964977275754_1803638_o.jpg",
           "baseVersion":"afe1994e-d9a8-47fd-a7db-dcf0e085fc05",
           "created":"2015-06-01T13:30:16.490Z",
           "lastModified":"2015-06-01T13:30:16.490Z",
           "isCheckedOut":true,
           "createdBy":"admin",
           "versionHistory":"152eb76a-e0ac-446d-a7e8-47b5e5c821ed",
           "primaryType":"file",
           "lastModifiedBy":"admin",
           "uuid":"25cc6435-6432-47f3-8dc3-f94f2788f2ef",
           "parent":"9731cedc-8ed7-4367-b95d-30898c7913a1",
           "mimeType":"image/jpeg",
           "size":116285
        },
        {
           "name":"Child1",
           "created":"2015-04-07T21:03:41.729Z",
           "createdBy":"admin",
           "primaryType":"folder",
           "uuid":"f8d1ffed-9b51-4982-97b7-60f8e074eda4",
           "parent":"9731cedc-8ed7-4367-b95d-30898c7913a1",
           "itemCount":36
        },
        {
           "name":"Child2",
           "created":"2015-04-07T21:14:47.950Z",
           "createdBy":"admin",
           "uuid":"8f1246ff-5053-411a-88de-c465027b998d",
           "primaryType":"folder",
           "parent":"9731cedc-8ed7-4367-b95d-30898c7913a1",
           "itemCount":3
        },
        {
           "name":"Child3",
           "created":"2015-05-01T00:46:36.973Z",
           "createdBy":"admin",
           "uuid":"54f897a4-ac16-4585-83cb-d0e67ca73a74",
           "primaryType":"folder",
           "parent":"9731cedc-8ed7-4367-b95d-30898c7913a1",
           "itemCount":1
        },
        {
           "name":"Child4",
           "created":"2015-05-26T18:18:33.159Z",
           "createdBy":"admin",
           "primaryType":"folder",
           "uuid":"ad1344a9-08b7-44bb-b47d-0efb99c59ac3",
           "parent":"9731cedc-8ed7-4367-b95d-30898c7913a1",
           "itemCount":0
        },
        {
           "name":"Child5",
           "created":"2015-06-07T03:57:20.494Z",
           "createdBy":"admin",
           "primaryType":"folder",
           "uuid":"2b46d7e4-b50e-4eec-b97a-c46b2016926c",
           "parent":"9731cedc-8ed7-4367-b95d-30898c7913a1",
           "itemCount":0
        },
        {
           "name":"content.jpg",
           "baseVersion":"620c8448-3e51-4a27-b630-60c1272c19da",
           "created":"2015-06-03T15:09:25.192Z",
           "lastModified":"2015-06-03T15:09:25.193Z",
           "isCheckedOut":true,
           "createdBy":"admin",
           "versionHistory":"871afa2a-5a2c-4762-bc26-a69022234850",
           "primaryType":"file",
           "lastModifiedBy":"admin",
           "uuid":"c8c63420-b525-4b36-bce3-a7c4cc55c07a",
           "parent":"9731cedc-8ed7-4367-b95d-30898c7913a1",
           "mimeType":"image/jpeg",
           "size":30711
        }
     ]
  }

1 个答案:

答案 0 :(得分:1)

我将大部分逻辑移到另一个函数中并将该函数包装在Promise中。我不确定以递归方式为树的每个分支创建promise是有什么好处的。该函数是非阻塞的,对逻辑的改动很小。

function deepFindReturn (object, searchKey, searchVal) {
  function doer(object, searchKey, searchVal) {
    if ( object[searchKey] === searchVal ) {
      return object;
    }

    for(let x in object) {
      let val = object[x];

      if (typeof val === typeof searchVal) {
        continue;
      }

      if ( Array.isArray( val ) ) {
        for (let item of val) {
          let o = doer(item, searchKey, searchVal);
          if (o) {
            return o;
          }
        }
      }
      else if ( typeof val === 'object' ) {
        let o = doer(val, searchKey, searchVal);
        if (o) {
          return o;
        }
      }
    }
  };

  return new Promise(function(resolve) {
    resolve(doer(object, searchKey, searchVal));
  });
}

deepFindReturn(data, 'uuid', 'f8d1ffed-9b51-4982-97b7-60f8e074eda4')
  .then((o) => { console.log(o); });

Live Demo

但是,如果练习的重点是试验递归异步代码,我会看一下Async而不是promises。在递归情况下更有用。

我认为你能用promises做的唯一方法是为每次迭代生成一个Promise并将它们添加到一个新数组中。您将新数组传递给Promise.race。类似的东西:

Promise.race(val.map(function(item) {
  return new Promise(function(resolve) {
    // Determine result
    resolve(result);
  });
}))
  .then((result) => { /* Deal with result */ });