I need to perform a rather complicated chain of promise resolutions to get and save data that is located in PDFs that are uploaded by a user. Everything works fine for single PDFs, but it breaks as soon as I try to upload multiple PDFs because the order in which the resolution proceeds isn't as I expect.
I call the function saveDoc on each file in an array:
     saveDoc: function(){
         var files = this.$refs.upload.uploadFiles
         var self=this;
         var promises = []
         for (var i=0; i<files.length; i++){
             (function(){
                 var file = files[i]
                 var name = file['name']
                 if (!(/\.pdf/i.test(name))){
                     name+='.pdf'
                 }
                 var type = mime.lookup(name)
                 var file = file['raw'];
                 var beforeUrl = self.selectedCategories.join('&&&')
                 console.log('going to save: ' + name)   // Because of the IIFE, I'm not expecting this to log only after all steps 1 - 20 have been completed for each file
                 Store.getFileData(file).then(function(data){
                     console.log(2)
                     return Store.saveDoc(name, type, data, beforeUrl).then(url => {
                         console.log(8)
                         return Text.getText(url).then(text => {
                             console.log(12)
                             return Text.getMetadata(text, url).then(metadata => {
                                 console.log(20)
                                 if (metadata.length){
                                     return Store.saveMetadata(beforeUrl, metadata, name)
                                 }
                                 return Store.createCategory(name, self.selectedCategories, '')
                             })
                         })
                     })
                 })
             })()
         }
     },
I'm sure the promises could use some work, but what seems to be the problem is that the line console.log('going to save: ' + name) is called twice before the entire sequence 1-20 is carried out for one file (see error message of number sequence at bottom of this post).  I tried to prevent this using an IIFE, but I guess I didn't do this right.  
store.js
    getData: function(url){
        return new Promise(function(accept, reject){
            console.log(4)
            documentation.get(url, function(err, body) {
                console.log(5)
                if (!err){
                    console.log(body);
                    accept(body)
                }
            });
        })
    },
    getFileData: function(file){
        var reader = new FileReader();
        return new Promise(function(accept, reject){
            console.log(1)
            reader.onload = (e) => {
//              var data = e.target.result.replace(/^data:[A-Za-z]+\/[A-Za-z]+;base64,/, '')
                //              console.log('base 64: ' + data)
                var res = new Uint8Array(e.target.result)
                accept(res)
            };
            reader.readAsArrayBuffer(file);
        })
    },
    saveDoc: function(name, type, filedata, url){
        console.log(3)
        var self=this
        return new Promise(function(accept, reject){
            return self.getData(url).then(data => {
                console.log(6)
                var rev = data['_rev']
                return documentation.attachment.insert(url, name, filedata, type,
                                                { rev: rev }, function(err, body) {
                                                    if (!err){
                                                        console.log(7)
                                                        var fullUrl = 'http://dev04/documentation/'+url+'/'+name
                                                        accept(fullUrl)
                                                    }
                                                    else {
                                                        console.log(err)
                                                    }
                                                })
            }).catch(err => {
                console.log(err)
            })
        })
    },
    saveMetadata: function(url, metadata, name){
        var fileName = path.basename(name)
        var self=this
        return new Promise(function(accept, reject){
            self.getData(url).then(data => {
                var meta
                var rev = data['_rev']
                if(!data['metadata']){
                    data['metadata'] = {}
                }
                data['metadata'][fileName] = metadata
                var datastring = JSON.stringify(data)
                documentation.insert(data, url, function(err, body, header) {
                    if (err) {
                        console.log(err.message);
                        return;
                    }
                });
            }).catch(err => {
                console.log(err)
            })
        })
    },
text.js
export default {
    getText: function(url){
        console.log(9)
        var result = []
        return new Promise(function(accept, reject){
            console.log(10)
            return pdfjs.getDocument(url).then(pdf => {
                console.log(11)
                var pdf = pdfjs.getDocument(url);
                return pdf.then(function(pdf) { // get all pages text
                    var maxPages = pdf.pdfInfo.numPages;
                    var countPromises = []; // collecting all page promises
                    for (var j = 1; j <= maxPages; j++) {
                        var page = pdf.getPage(j);
                        var txt = "";
                        countPromises.push(page.then(function(page) { // add page promise
                            var textContent = page.getTextContent();
                            //                      console.log('the content is ' + textContent)
                            return textContent.then(function(text){ // return content promise
                                var val = text.items.map(function (s) { return s.str; }).join('&&&')+'&&&'; // value page text
                                result.push(val)
                                //                              console.log(val + ' should be one page of text')
                                return val
                            });
                        }));
                    }
                    // Wait for all pages and join text
                    return Promise.all(countPromises).then(function (texts) {
                        accept(texts.join(''))
                    });
                });
            });
        })
    },
    getMetadata: function(text, url){
        console.log(13)
        var result = []
        var self = this
        return new Promise(function(accept, reject){
            self.getpageno(url).then(function(pagecount){
                console.log(19)
                try {
                    var dataMatch = rx.exec(text)
                    var produktDaten = dataMatch[1].split("&&&").filter(Boolean);
                    console.log(produktDaten)
                    var dokuArr = dataMatch[2].split("&&&").filter(Boolean);
                    for (var i=0; i<produktDaten.length; i+=4){
                        var entry = {}
                        entry.pagecount = pagecount
                        entry.kks = {}
                        entry.kks.pages = {}
                        var kksNummer = produktDaten[i];
                        entry.kks.nummer = kksNummer;
                        for(var j=0; j<dokuArr.length; j+=3){
                            var nummer = dokuArr[j];
                            var beschreibung = dokuArr[j+1];
                            var seite = dokuArr[j+2];
                            // make sure seite is a digit
                            if (!(/^\d+$/.test(seite))){
                                console.log(seite + ' was not a valid page number')
                                throw err
                            }
                            if (/(A|a)lle?/i.test(nummer)){
                                entry.kks.pages[beschreibung] = seite;
                                //                  self.tableEntry.kks.url = url;
                                //                  self.tableEntry.fileName = name;
                                /////               kksNummern.forEach(function(kks){
                                //                      self.tableEntry.kks;
                                //                  })
                            }
                            else if (nummer === kksNummer) {
                                entry.kks.pages[beschreibung] = seite;
                                //                  entry.kks.url = url;
                                //                  entry.fileName = name
                            }
                        }
                        entry.hersteller = produktDaten[i+1]
                        entry.typ = produktDaten[i+2]
                        entry.artikelNummer = produktDaten[i+3]
                        result.push(entry)
                    }
                }
                catch(e){
                    return accept(result)
                }
                return accept(result)
                /*              if (result.length>0){
                    console.log('accepting the result')
                }
                reject()*/
            }).catch(err => {
                console.log(err)
            })
                })
    },
    getpageno: function(url){
        console.log(14)
        var self=this
        var pdf = pdfjs.getDocument(url);
        return pdf.then(function(pdf){
            console.log(15)
            var maxPages = pdf.pdfInfo.numPages;
            var countPromises = []; // collecting all page promises
            for (var j = 1; j <= maxPages; j++) {
                try {
                    var page = pdf.getPage(j);
                    var txt = "";
                    countPromises.push(page.then(function(page) { // add page promise
                        var textContent = page.getTextContent();
                        return textContent.then(function(text){ // return content promise
                            console.log(16)
                            return text.items.map(function (s) { return s.str; }).join('&&&'); // value page text
                        });
                    }));
                }
                catch(e){
                    console.log(e)
                }
            }
            // Wait for all pages and join text
            return Promise.all(countPromises).then(function (texts) {
                // since doumentation pages do not add the final '&&&', must add one manually (only after rx has been found)
                console.log(17)
                var fulltext = texts.reduce(function(full, text){
                    if (rx.test(full)){
                        var next = '&&&'+text
                        return full+=next
                    }
                    return full+=text
                }, '')
                return [fulltext, texts]
            });
        }).then(function(textarr){
            console.log(18)
            var fulltext = textarr[0]
            self.fulltext = fulltext;
            var texts = textarr[1]
            try {
                var partialmatch = rx.exec(fulltext)[0]
                var count = texts.reduce(function(pageno, text){
                    var tomatch = text.replace(/.*Typ&&&/, '')
                    if (tomatch.length>0 && partialmatch.indexOf(tomatch) > -1){
                        pageno++
                    }
                    return pageno;
                }, 0)
            }
            catch(e){
                console.log(e)
            }
            return count;
        }).catch(err => {console.log(err)})
    }
}
I use the console to log the order I am expecting for the functions. I am expecting the numbers 1 - 20 in order, but I get the following.
    going to save: 03_.pdf  selector.js:211:6
1  store.js:227:4
going to save: 2017.07.05_0016 E161206.pdf  selector.js:211:6
1  store.js:227:4
2  selector.js:213:7
3  store.js:239:3
4  store.js:213:4
2  selector.js:213:7
3  store.js:239:3
4  store.js:213:4
5  store.js:215:5
Object { _id: "Test", _rev: "36-85a08c0852ccab78c0b4c10369e83fb2", rank: 7, icon: "wrench", metadata: Object, _attachments: Object }  store.js:217:6
6  store.js:243:5
5  store.js:215:5
Object { _id: "Test", _rev: "36-85a08c0852ccab78c0b4c10369e83fb2", rank: 7, icon: "wrench", metadata: Object, _attachments: Object }  store.js:217:6
6  store.js:243:5
7  store.js:247:7
8  selector.js:215:8
9  text.js:12:3
10
11  text.js:17:5
12  selector.js:217:9
13  text.js:50:3
14  text.js:112:3
15  text.js:116:4
16 text.js:129:8
17  text.js:142:5
18  text.js:153:4
19  text.js:57:5
20
Can anyone offer any advice on how to get this order correct? Thank you.
