我尝试遍历一堆HAL / JSON资源,这些资源为通过hrefs连接并通过https检索的项目树建模。也就是说,“项目”可以是请假或其他分支与其他叶子。las,我做对了。遍历将始终结束,即在完成完整递归之前,在我的代码示例的最后一条语句中命中then()回调。实际上,我只将第一层放回了孩子中。
我的问题:我错过了什么才能做到正确?
我仍在学习Node.js,但是我已经在较早的示例中成功使用了Promise。我在这里问这个问题,因为我只能使用模块https和集成的Nodejs东西。其他示例经常使用其他模块和/或不能解决我遇到的问题。
var traverse = function(rootItemUrl, depth, children) {
var deferred = Promise.defer();
var itemUrl = rootItemUrl;
var options = {
'path' : itemUrl
, 'host' : "<host>"
, 'method' : 'GET'
, 'headers' : {
'Content-Type' : 'application/json'
, 'Accept' : 'application/json'
, 'Forwarded' : 'proto=https;host=<host>'
, 'Cookie' : options_.headers['Cookie']
}
};
https.get(options, onItemResultResponse);
function onItemResultResponse(itemResultResponse) {
var body = [];
itemResultResponse.on('data', function onDataChunk(data) {
body.push(data);
});
itemResultResponse.on('end', onItemResultData);
itemResultResponse.on('error', onRequestItemsError);
function onRequestItemsError(e) {
console.log('Get items failed for <'+rootItemUrl+'>.');
deferred.reject();
}
function onItemResultData() {
var items = [];
var itemResult = JSON.parse(Buffer.concat(body).toString());
var embedded = itemResult._embedded;
var collection = embedded ? embedded['collection'] : undefined;
if(collection) {
var itemsObject = collection._links['item'];
if(itemsObject) {
if(itemsObject.length) {
for(var i = 0; i < itemsObject.length; ++i) {
items.push(itemsObject[i].href);
}
} else {
items.push(itemsObject.href);
}
}
}
var type = itemResult.base.type;
var name = itemResult.common.name;
var text = repeatChar(depth, '\t') + ('folder' === type ? '- (folder) ' : '')+ 'depth: '+depth+' '+name;
children.push(text);
//console.log(text);
if(items.length) {
for (var j = 0; j < items.length; ++j) {
traverse(items[j], depth + 1, children)
.then(function() {deferred.resolve(depth);});
}
} else {
deferred.resolve(depth);
}
}
}
return deferred.promise;
};
var children = [];
traverse(rootItemUrl, 0, children)
.then(function toConsole(depth) {
// >> Alas I hit this point too early <<
console.log(children);
console.log('End');
});
对于对此答案感兴趣的人,请继续阅读,因为我找到了一个没有承诺的解决方案。我完全摆脱了对回调的承诺。请注意,与原始代码相比,我进行了一些更改,例如,收集结果而不是将它们打印到递归代码中的stdout中,并且删除了其他一些绒毛。
var traverse = function(options, rootItemUrl, depth, done) {
var results = [];
options.path = rootItemUrl;
https.get(options, onItemResultResponse);
function onItemResultResponse(itemResultResponse) {
var body = [];
itemResultResponse.on('data', function onDataChunk(data) {
body.push(data);
});
itemResultResponse.on('end', onItemResultData);
itemResultResponse.on('error', onRequestItemsError);
function onRequestItemsError(e) {
console.log('Get items failed for <' + rootItemUrl + '>.');
done(e);
}
function onItemResultData() {
var items = [];
var itemResult = JSON.parse(Buffer.concat(body).toString());
var embedded = itemResult._embedded;
results.push(toItemInfo(itemResult, depth));
var collection = embedded ? embedded['collection'] : undefined;
var embeddedItems = collection ? collection._embedded : undefined;
if (embeddedItems) {
var itemsObject = embeddedItems['item'];
if (itemsObject) {
if (itemsObject.length) {
for (var i = 0; i < itemsObject.length; ++i) {
items.push(itemsObject[i]);
}
} else {
items.push(itemsObject);
}
}
var itemInfos = new Array(items.length);
for (var iii = 0; iii < items.length; ++iii) {
itemInfos[iii] = toItemInfo(items[iii], depth + 1);
}
var ii = 0;
(function next() {
var nextItemInfo = itemInfos[ii++];
if (!nextItemInfo) {
return done(null, results);
}
if ('folder' === nextItemInfo.type) {
traverse(options, nextItemInfo, depth + 1, function done(err, result) {
results = results.concat(result);
next();
});
} else {
results.push(nextItemInfo);
next();
}
})();
}
}
}
};
traverse(options, rootItemUrl, 0, function done(e, results) {
var text = '';
for(var ii = 0; ii < results.length; ++ii) {
var itemInfo = results[ii];
text += repeatChar(itemInfo.depth, '\t') + ('folder' === itemInfo.type ? '- (folder) ' : '') + 'depth: ' + itemInfo.depth + ' ' + itemInfo.name;
}
console.log(text);
console.log("End");
});
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句