【问题标题】:Promises in recursive algorithms not working - Node.JS递归算法中的承诺不起作用 - Node.JS
【发布时间】:2017-12-06 11:00:33
【问题描述】:

我正在使用 node.js 中的控制器将数据插入数据库。我要放入 db 的数据是多级 JSON。我想使用递归函数来解开 json 中的数组并将它们放在 db 中的不同表中。函数如下所示:

function LoopThroughObject(obiekt,masterKey,relation){
if(!relation) var undef = true
for(key in obiekt){
    if(obiekt[key].constructor === Array){
        LoopThroughObject(obiekt[key],key,relation)
    } else if(obiekt[key].constructor === Object){
        var pp
        (function(v1,v2){       
           pp = db.InsertData(masterKey,output)
            when(pp,function(data){         
                    LoopThroughObject(v1,v2,data.insertId)
                }, function(err){     
                }) 
            p.push(pp) 
        })(obiekt[key],masterKey)
        }     
    if(undef) relation = ''  
}    
}

该函数正常工作,但承诺除外。这是我正在执行的代码:

var input =  {projectsData:
            [{  name:'test_project',
                desc:'test description',
                date_start:'21.01.2017',
                date_end:'25.01.2017',
                date_ddl:'24.01.2017',
                tagsData:[{tag:10},{tag:2},{tag:3},{tag:4},{tag:5}],
                usersCoData:[{user:20,role:1},
                             {user:1,role:2},
                             {user:3,role:2}
                            ]
            }]
        }

var when = require("promised-io/promise").when  

LoopThroughObject(input,'','')

group = require("promised-io/promise").all(p);

group.then(function(){
   console.log('Success')
},function(){
    console.log('Fail')
});

现在,我遇到的问题是承诺。执行脚本后,函数 promises.all 总是返回成功。即使输入 json 中存在故意错误。如果我将它转储到控制台中,它看起来就像 promises.all 在抛出错误之前被触发了。所以我想这是递归模式的某种问题,但不知道如何解决它。请帮忙!

编辑 为了更好地熟悉递归承诺,我做了一些挖掘工作。我创建了以下示例(db 模块已经在使用 Promise),但仍然无法使其工作:

function loopviarecursive(i){
var q = new Deferred();
if(i<10){
    db.InsertData('projects',{  
project_name:'test_project'}).then(function(data){
        i++
        q = loopviarecursive(i)
        console.log('Iteration  '+i)
    }, function(err){
        console.log('Fail to insert')
        q.reject(err)
    })
}else {
    q.resolve()
}
return q.promise
}

var d = loopviarecursive(0)
when(d,function(){console.log('sucess')},function(){console.log('fail')})

欢迎任何关于如何使它工作的建议:)

【问题讨论】:

  • Promise 不会神奇地知道你想要什么......你的 LoopThroughObject 代码在许多层面上存在根本缺陷 - 一方面,你在任何异步代码之前运行 .all(p)有机会运行,并“填充”p(这是未声明的,所以p.push 甚至如何工作!!!)
  • if(!relation) var undef = true 基本上就是var undef = !relation
  • 好的,感谢您的意见。所以我应该修改函数,让它在 first 被解决后调用自己?

标签: javascript json node.js recursion


【解决方案1】:

那是因为你没有在 Promise 中调用 LoopThroughObject,LoopThroughObject 也没有返回一个 Promise,而且你还没有定义应该是一个 Promise 数组的 p(这没有意义,因为你只有一个 Promise) .

我猜在你的情况下你不需要 Promise,因为你不会异步加载数据,是吗?

也许this article 会帮助您了解如何以及何时使用 Promises。

我希望这会有所帮助:)

【讨论】:

  • p 应该定义好了,可能我这里没有复制。至于异步加载数据,我在每次调用函数时都这样做。这样同级别的json就可以并行插入了
  • 好的,但是你什么时候达到“结束”状态?因为现在你在 Promise 之外调用 LoopThroughObject 并且你没有返回一个 Promise 然后添加一个 .then 回调
  • @lumio - 我敢冒险db.InsertData(masterKey,output) 可能会返回一个承诺,或者至少是异步的
  • 实际上我是在 db insert (async) 的承诺中调用它,我的理解是它应该等到所有承诺都得到兑现
  • 啊!但是会不会是when语句前少了一个点
猜你喜欢
  • 2018-05-29
  • 2018-05-28
  • 1970-01-01
  • 1970-01-01
  • 2014-06-30
  • 2014-02-04
  • 1970-01-01
  • 2017-08-06
  • 1970-01-01
相关资源
最近更新 更多