how to accumulate a foreach loop promise return

2705 views loops
4

for example am trying to recursively get the file size of all items under a folder in cordova so i have something like

getDirSize(path) {
    return this.listDir(path).then((data) => {
        let size = 0

        data.dirs.forEach((dir) => {
            size += this.getRecursiveSize(dir.files)
        })

        if (data.files.length) {
            size += this.getRecursiveSize(data.files)
        }

        return size
    })
}

getRecursiveSize(files) {
    let size = 0

    files.forEach((item) => {
        this.getFileMeta(item.url).then((file) => {
            size += file.size
        })

        if (item.files) {
            size += this.getRecursiveSize(item.files)
        }
    })

    return size
}

which is called through

getDirSize(path).then((size) => {
    console.log(size)
})

however this doesn't work because the getFileMeta() is a promise, i know about promise.all() but am not sure how to use it properly to get the final size of all items.

answered question

1 Answer

5

so you can put all of the getFileMeta() calls in an array using map and Promise.all. Promise.all will take a an array of promises and set whatever is resolved within each into an array. So you get back an array of fileMetaData in this case, which you can use as any other array (after the Promise.all is finished --.then)..

const filesMetaData = Promise.all(files.map(file => new Promise(this.getFileMeta(file.url))))
filesMetaData.then(
fileMetaData // became an array here because of Promise.all
=> fileMetaData.reduce((accumulatedSize, file) => {
accumulatedSize += file.size
return accumulatedSize
})

posted this

Have an answer?

JD

Please login first before posting an answer.