2017-07-03 41 views
0

我正在爲控制器在node.js中插入數據到數據庫中。我想要放入數據庫的數據是多級JSON。我想要使​​用遞歸函數來展開json中的數組,並將它們放入db中的不同表中。功能如下所示:在遞歸算法無法工作的承諾 - Node.JS

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') 
}); 

現在,我遇到的問題是承諾。在執行腳本之後,函數會保證函數總是返回成功。即使在輸入json中有故意的錯誤。如果我將它轉儲到控制檯中,它看起來像promises.all在拋出錯誤之前被觸發。所以我想這是遞歸模式的一些問題,但不知道如何解決它。請幫忙!

編輯 爲了更好地熟悉遞歸承諾,我做了一些小小的挖掘工作。我創建了下面的例子(DB modlue已經在使用的承諾),但仍不能使其工作:

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')}) 

如何使它工作的任何意見是最歡迎:)

+1

承諾不是神奇地知道自己想要什麼......你LoopThroughObject代碼是在多個層面上存在根本性的缺陷 - 一件事,你運行'。所有(P )'在任何異步代碼甚至有機會運行之前,並且「填充」'p'(它是未聲明的,那麼'p.push'如何工作!!!) –

+0

'if(!relation)var undef = true'基本上是'var undef =!relation' –

+0

好的,謝謝你的輸入。所以我應該修改該函數,以便在第一次解決問題後調用它自己? – user1857756

回答

0

這是因爲你不會在Promise中調用LoopThroughObject,LoopThroughObject也不會返回一個promise,並且你還沒有定義p應該是promise的數組(這是沒有意義的,因爲你只有一個Promise)。

我想你的情況你不需要一個承諾,因爲你不加載數據異步,是嗎?

也許this article將幫助您找出如何以及何時使用承諾。

我希望這將有助於:)

+0

p應該被定義,可能我沒有在這裏複製它。至於不同步加載數據,我正在爲每個函數調用。所以,json的相同級別可以被pararelly插入 – user1857756

+0

好吧,但是你什麼時候「結束」 - 狀態達到了?因爲現在你在Promise外面調用LoopThroughObject,並且你還沒有返回一個Promise,然後添加一個'.then'回調 – lumio

+0

@lumio - 我敢說'db.InsertData(masterKey,output)'可能會返回一個承諾,或者至少是,異乎尋常的 –