2017-12-29 37 views
1

プロミスを使用してデータベーステーブルを歩き回り、各ステップからデータを同期的に取得したいと考えています。私は私のコードは次のようになるはずだと思う:Promiseでテーブルウォーク/再帰

function get_next_id(the_id) { 
    return new Promise(function(resolve) { 
     connection.query(get_parent_query, [ the_id ], function (e, r, f) { 
      resolve(r[0].from_visit); 
     }); 
    }); 
} 

var page_id = 60239; 
while (page_id > 0) { 
    get_next_id(page_id).then((i) => page_id = i); 
} 

このコードの問題は、その後すぐに()が完了するのを待たずにループ反復します。

this answerでは、Promise.race()を使用するか、約束を放棄してasyncを推奨します。

+0

答えは* * 2015年にあったことを。それ以来変化してきた... –

答えて

0

を私はあなたがIDの束を取得したい理由を理解できないが、結果で何もしません。あなたの元の機能はほぼそこにありましたが、何か問題が生じた場合は、これまでのエラーと結果を拒否すべきです。

すべてが右に行けば、すべての結果を解決:

function get_next_id(the_id,results=[]) { 
    return new Promise(function (resolve,reject) { 
    connection.query(get_parent_query, [the_id], function (e, r, f) { 
     if(e){ 
     //reject if something goes wrong with error and 
     // what has been done so far 
     reject([e,results]); 
     return; 
     } 
     resolve(r); 
    }); 
    }) 
    .then(function (r){ 
    if(r[0].from_visit===0){ 
     return results; 
    } 
    //recusively call unless id is 0 
    return get_next_id(r[0].from_visit,results.concat(r)) 
    }); 
} 

get_next_id(22) 
.then(
    results=>console.log("got results:",results) 
    ,([error,resultsSoFar])=>console.error(
    "something went wrong:",error, 
    "results before the error:",resultsSoFar 
) 
); 
+0

ありがとう、私はこのコードをリンクされたデータのリストを構築するために働かせました。私はsqliteに切り替えることになったので、コードをシンプルにする同期ライブラリを使用することができました。 –

2

は非同期/のawait使用できます

(async function(){ 

    var pageId = 60239; 
    while (page_id > 0) { 
    pageId = await get_next_id(pageId); 
    } 

})() 

または間接的な再帰を使用します。

(function next(pageId){ 
    if(pageId <= 0) return; 
    get_next_id(pageId).then(next); 
})(60239); 
+0

ありがとう、間接再帰アプローチは私のために働く。 –