Javascript обещает не решить в ожидаемом порядке - PullRequest
0 голосов
/ 23 ноября 2018

Я написал функцию для изменения идентификатора документов couchdb, которые я называю «категориями», которые могут включать вложения.Для этого требуется несколько асинхронных операций - вставка нового документа, копирование номера редакции, копирование вложений, удаление старого документа и т. Д. - поэтому я использую обещания.

Эти категории могут включать в себя подкатегории до n-й степени, идентификаторы которых начинаются с названия категории и разделяются знаком & &&.Например, это действительные идентификаторы:

"category"
"category&&&subcategory&&&subsubcategory"

Моя проблема в том, что эти операции выполняются не в том порядке, в котором я ожидаю.Я добавил комментарии и журналы консоли, показывающие, что я ожидаю увидеть в журнале.Однако фактический заказ, который регистрируется, когда есть вложения, которые нужно скопировать, выглядит примерно так:

1 store.js:365
2 store.js:367
2 store.js:367
2 store.js:367
2 store.js:367
3 store.js:383
4 store.js:385
3 store.js:383
4 store.js:385
3 store.js:383
4 store.js:385
5 store.js:388
5 store.js:388

функция:

function renameCategory(path, newname){
    var self=this
    return new Promise(function(completed, failed){
        function addAttachment(obj, key, path, newname){
            return new Promise(function(accept, reject){
                var full = `${protocol}://${serverName}/documentation/${path}/${key}`
                self.getFileData(full, true).then(data => {
                    console.log('got the file data')
                    self.saveDoc(key, 'application/pdf', data, newname).then(function(fullurl){
                        accept()
                    })
                })

            })
        }
        function produceCopies(path){
            self.getCategories().then(cats => {
                var result = cats.map(cat => {
                    var rx = new RegExp('^' + path + '(&&&)?')
                    if (rx.test(cat['id'])){
                        return cat['id']
                    }
                }).filter(x => {return x != undefined}).sort((a,b) => {
                    return a.length < b.length
                })
                return Promise.all(result.map(url => {                     //   EACH 'URL' SHOULD BE PROCESSED IN ORDER SO THAT 1, 2, 3, ... SHOULD BE LOGGED IN ORDER...
                    console.log(1)                                         //   STEP 1
                    return self.getData(url).then(data => {
                        console.log(2)                                     //   STEP 2
                        var updatedName = url.replace(path, newname)
                        var obj = Object.assign({}, data)
                        delete obj['_rev']
                        obj._id = updatedName
                        try {
                            delete obj._attachments[url+'.csv']
                        }
                        catch(e){
                        }
                        if (obj['_attachments']){
                            var attachmentKeys = Object.keys(obj['_attachments'])
                            console.log(attachmentKeys + ' are the attachment keys')
                            delete obj._attachments
                            return documentation.insert(obj, updatedName, function(err, body) {
                                if (!err){
                                    console.log(3)                          //  STEP 3
                                    return Promise.all(attachmentKeys.map(key => {
                                        console.log(4)                      //  STEP 4
                                        return addAttachment(obj, key, path, newname).then(function(){
                                            console.log(5)                  //  STEP 5
                                            return self.deleteCategory(url).then(function(){
                                            })
                                        })
                                    }))
                                }
                                else {
                                    failed(err)
                                }
                            })
                        }
                        else {
                            console.log('no attachments found')
                            return documentation.insert(obj, updatedName, function(err, body) {
                                if (!err){
                                    return self.deleteCategory(url).then(function(){

                                    })
                                }
                                else {
                                    failed(err)
                                }
                            })
                        }
                    })
                })).then(function(){
                    completed()
                })
            })
        }
        produceCopies(path)
    })

}

Может кто-нибудь помочь мне разобратьсякак заставить эти обещания разрешаться в правильном порядке, чтобы консоль выводила 1, 2, 3, 4, 5?

...