我正在使用NodeJs和Box SDK。
我需要获取目录中所有文件和文件夹的数据,因此我要检查每个文件夹中的子文件夹和文件,将数据保存在数组中,然后再次调用该函数子文件夹。
问题是我无法从递归调用中获取包含所有数据的数组,我无法找出返回或解析函数checkChilds
的位置,也无法处理的承诺。
我需要的是一个承诺,一旦for循环完成并且所有堆栈都完成就会解析,这样arrayIds
将在完成所有操作后获得所有数据。
我的主目录中的文件夹结构分为预览和生产,所以我也检查它在数组中的位置。
这是我的代码:
var boxUtil = require('../utils/boxUtils')
var boxInstance = boxUtil.getBOXInstance()
exports.script = function (request, response) {
var accessToken = request.headers.authorization
var folderId = request.body.folderId
var userId = request.body.user
var arrayIds = []
boxInstance = boxUtil.getBOXInstance()
if (boxInstance == null) {
boxUtil.initBOXInstance(userId, function (error, res) {
if (error) {
response.status(500)
return response.send(error.message)
}
boxInstance = res
var box = boxInstance.getBasicClient(accessToken)
var func = getFolderInfo(folderId, arrayIds, box)
.then(checkIfPreviewOrProduction)
.then(insertInPreviewOrProduction)
.then(iAmRecursive)
.then(stringLogMe)
.then(null, console.log)
})
} else {
console.log('RESTART SERVER AND TRY AGAIN PLEASE')
}
}
function iAmRecursive ([resp, arrayIds, boxInstance]) {
return new Promise(function (resolve, reject) {
function checkChilds ([resp, arrayIds, boxInstance]) {
if (resp.item_collection.total_count > 0) {
for (var j = 0; j < resp.item_collection.entries.length; j++) {
if (resp.item_collection.entries[j].type === 'folder') {
getFolderInfo(resp.item_collection.entries[j].id, arrayIds, boxInstance)
.then(insert)
.then(checkChilds)
.then(null, console.log)
}
if (resp.item_collection.entries[j].type === 'file') {
ifFileChild([resp.item_collection.entries[j], arrayIds, boxInstance])
}
}
} else {
console.log('no childs were found')
}
}
checkChilds([resp, arrayIds, boxInstance])
})
}
function stringLogMe (stringifyMe) {
var text = console.log(JSON.stringify(stringifyMe, null, 2))
return text
}
function getFolderInfo (folderId, arrayIds, boxInstance) {
return new Promise(function (resolve, reject) {
var query = {fields: 'id,name,item_collection,path_collection'}
boxInstance.folders.get(folderId, query, function (err, resp) {
if (err) {
reject(err)
} else {
resolve([resp, arrayIds, boxInstance])
}
})
})
}
function getMetadata ([resp, arrayIds, boxInstance]) {
return new Promise(function (resolve, reject) {
var fileId = resp.id
boxInstance.files.getAllMetadata(fileId, function (err, response) {
if (err) {
reject(err)
} else {
response.name = resp.name
response.type = resp.type
resolve([response, arrayIds, boxInstance])
}
})
})
}
function insert ([resp, arrayIds, boxInstance]) {
return new Promise(function (resolve, reject) {
if (resp.type === 'file') {
var newObject = {
'id': resp.id,
'name': resp.name,
'type': resp.type,
'entries': resp.entries
}
} else {
var newObject = {
id: resp.id,
name: resp.name,
type: resp.type
}
}
arrayIds.push(newObject)
resolve([resp, arrayIds, boxInstance])
})
}
function ifFileChild ([resp, arrayIds, boxInstance]) {
return new Promise(function (resolve, reject) {
getMetadata([resp, arrayIds, boxInstance])
.then(insert)
.then(null, console.log)
})
}
我的函数iAmRecursive
是应该使用promise链中的完整数组解析的函数。
我已经阅读了几个类似的问题,但我无法使用递归调用做任何事情。
如果您需要进一步澄清问题,请告诉我。
答案 0 :(得分:0)
我稍微重构了这个函数。它现在将收集所有承诺并在解决后立即解决。
function iAmRecursive([resp, arrayIds, boxInstance]) {
var promises = [];
for (var j = 0; j < resp.item_collection.entries.length; j++) {
if (resp.item_collection.entries[j].type === 'folder') {
promises.push(getFolderInfo(resp.item_collection.entries[j].id, arrayIds, boxInstance)
.then(insert)
.then(iAmRecursive)
.then(null, console.log)
)
}
if (resp.item_collection.entries[j].type === 'file') {
promises.push(ifFileChild([resp.item_collection.entries[j], arrayIds, boxInstance]));
}
}
return Promise.all(promises);
}
由于评论而进行编辑。你没有解决你的一些承诺。
更改
function ifFileChild ([resp, arrayIds, boxInstance]) {
return new Promise(function (resolve, reject) {
getMetadata([resp, arrayIds, boxInstance])
.then(insert)
.then(null, console.log)
})
}
要
function ifFileChild ([resp, arrayIds, boxInstance]) {
return getMetadata([resp, arrayIds, boxInstance])
.then(insert)
.then(null, console.log)
}
如果您要立即与另一个人一起解决,那么创建一个新的承诺是多余的。但是,如果你不得不,如果有其他异步解析分支,你需要这样的东西:
function ifFileChild ([resp, arrayIds, boxInstance]) {
return new Promise(function (resolve, reject) {
if( /* condition*/){
setTimeout(function(){ resolve("jea"); }, 5000);
}
else{
resolve( getMetadata([resp, arrayIds, boxInstance])
.then(insert)
.then(null, console.log)
)
}
})
}
您可以使用它来展平数组:
var flat = (function flatten(result, current){
return result.concat( Array.isArray(current) ? current.reduce(flatten, []) : current )
})([], array);