2016-07-21 8 views
0

データベースに階層をロードしようとしています。私はすべての行が親を持つことができるように、私のテーブルにparentIdを持つ列を持っています。しかし、私は再帰と約束を使って問題を抱えています。だから、sequelize/nodejsを使用するherarchyクエリ

function read (options) { 
    return serviceItemAttributeModel.findOne({ 
    id: options.id, 
    id_organization: options.idOrganization 
    }) 
    .then((attribute) => { 
    if (attribute) { 
     return loadChildren(attribute, attribute); 
    } else { 
     return attribute; 
    } 
    }); 
} 

function loadChildren (root, attribute) { 
    return serviceItemAttributeModel.findAll({ 
    where: { 
     id_parent: attribute.id 
    } 
    }) 
    .then((attributes) => { 
    if (!attributes) { 
     return root; 
    } else { 
     attribute.serviceItemAttributes = []; 
     attributes.forEach(function (each) { 
     attribute.serviceItemAttributes.push(each); 
     return loadChildren(root, each); 
     }); 
    } 
    }); 
} 

、私はを呼び出す再帰(エンティティの子供たちを見ることによって)すべてのエンティティをロードしようと、私は未定義の値を取得するためにloadChildrenを呼び出すことをお読みください。何か案は?

私もコンソールでエラーが表示されます:約束はハンドラで作成されましたが、返されませんでした。

EDIT:Nosyaraヘルプ後に、このソリューション場合

を思い付きました。ありがとう!:

function read (options) { 
    return serviceItemAttributeModel.findOne({ 
    where: { 
     id: options.attributeId, 
     id_organization: options.idOrganization 
    } 
    }) 
    .then((attribute) => { 
    if (!attribute) { 
     return new Promise(function (resolve, reject) { 
     resolve(attribute); 
     }); 
    } else { 
     return new Promise(function (resolve, reject) { 
     attribute.queryCount = 1; 
     resolve(attribute); 
     }) 
     .then((attribute) => loadChildren(attribute, attribute)); 
    } 
    }); 
} 

function loadChildren (root, attribute) { 
    return new Promise(function (resolve, reject) { 
    return serviceItemAttributeModel.findAll({ 
     where: { 
     id_parent: attribute.id 
     } 
    }) 
    .then((attributes) => { 
     attributes.length = attributes.length || 0; 
     root.queryCount = root.queryCount - 1 + attributes.length; 
     if (root.queryCount === 0) { 
     resolve(root); 
     } else if (root.queryCount > 10) { 
     let error = new Error('Service attribute hierarchy cant have more then 10 levels'); 
     error.statusCode = 500; 
     reject(error); 
     } else { 
     attribute.serviceItemAttributes = []; 
     attributes.forEach(function (each) { 
      attribute.serviceItemAttributes.push(each); 
      return loadChildren(root, each).then(() => { 
      resolve(root); 
      }); 
     }); 
     } 
    }); 
    }); 
} 

答えて

0

あなたは非同期呼び出しを混乱させて返します。両方の関数を非同期に変換し、結果構造を渡して更新することができます。例:

function read(...) { 
    return new Promise(function (accept, reject) { 
    // You code goes here, but instead of return 
    accept(resultFromAsyncFunction); 
    }); 
} 
// ... 
read(...).then(function(resultData) { ... }); 

HereはPromise再帰の例です。

+0

私はあなたのように見えるようにコードを変更し....しかし、それはまだdidntの仕事 – fredcrs

+0

は、いくつかの進歩.....まだカントロード第三レベル – fredcrs

+0

コードこれまでに得た:http://pastebin.com/Na5NHkMm – fredcrs

関連する問題