使用 ES6 Promise 的递归树遍历
Recursive Tree Walk with ES6 Promise
我正在寻找通过 ES6 承诺遍历未知深度的对象树和 return 给定节点。 (我意识到这里使用了 lodash,显然没有必要)。我的树行走工作正常但我有点不清楚确保顶级范围变量 promise
被传递到递归函数调用以便在调用 [=13= 时可用的正确方法].现在它尝试执行成功的查找但未能解决承诺,因为递归函数已被新承诺覆盖并且无法在链上冒泡:
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
}
]
}
我会将大部分逻辑移动到另一个函数中并将该函数包装在 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); });
但是,如果练习的目的是试验递归异步代码,我会看一下 Async 而不是 promises。在递归情况下更有用。
我认为你可以用 promise 做到这一点的唯一方法是为每次迭代生成一个 Promise
并将它们添加到一个新数组中。您将该新数组传递给 Promise.race。类似于:
Promise.race(val.map(function(item) {
return new Promise(function(resolve) {
// Determine result
resolve(result);
});
}))
.then((result) => { /* Deal with result */ });
我正在寻找通过 ES6 承诺遍历未知深度的对象树和 return 给定节点。 (我意识到这里使用了 lodash,显然没有必要)。我的树行走工作正常但我有点不清楚确保顶级范围变量 promise
被传递到递归函数调用以便在调用 [=13= 时可用的正确方法].现在它尝试执行成功的查找但未能解决承诺,因为递归函数已被新承诺覆盖并且无法在链上冒泡:
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
}
]
}
我会将大部分逻辑移动到另一个函数中并将该函数包装在 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); });
但是,如果练习的目的是试验递归异步代码,我会看一下 Async 而不是 promises。在递归情况下更有用。
我认为你可以用 promise 做到这一点的唯一方法是为每次迭代生成一个 Promise
并将它们添加到一个新数组中。您将该新数组传递给 Promise.race。类似于:
Promise.race(val.map(function(item) {
return new Promise(function(resolve) {
// Determine result
resolve(result);
});
}))
.then((result) => { /* Deal with result */ });