2016-10-17 8 views
2

私はthis tutorialに従っていますが、今は、動作する接続プールを持つMySQLデータベースにExpress jsアプリケーションを構築しています。私はサーバーの命令の滝のためにAsync.jsを使用しています。ForYach関数は、Asyncの滝のMysql接続プールを持っています

私は自分のコードをコールバックヘリングを避けてリファクタリングしていました。私は非常に混乱しています。なぜなら、MySql接続を完全に取得したforEach関数(コールバック・ヘル状況)をネストした作業コードがあり、今は何も動作しないように見えるからです。

ISSUE: GETリクエストで を受信し、それがstucks"アクション二" まで印刷します。

は、これが私の現在のMWEです:

apiRoutes.get('/endpoint', function(req, res) { 
async.waterfall([ 
function actionOne(callback){ 
    connection.acquire(function(err, con){ 
     con.query(myQuery , function(err, result){ 
      con.release(); 
      if(err){ 
       console.log(err); 
       callback(err); 
      } else { 
       console.log("Action One Success"); 
       callback(null, result); 
      } 
     }); 
    }); 
}, 
function actionTwo(list, callback){ 
    console.log("Action Two"); 
    var arr = []; 
    list.forEach(function(item, index, array){ 
     item.arr = []; 
     connection.acquire(function(err, con){ 
      con.query(otherQuery , function(err, result){ 
       con.release(); 
       if(err){ 
        console.log("SQL ERROR: "+err); 
        callback(err); 
       } else { 
        item.arr = result; 
        arr.push(cult); 
        if(index === array.length-1){ 
         console.log("Action Two Success"); 
         callback(null, arr); 
        } 
       } 
      } 
     }); 
    }) 
}, 
function actionThree(item, callback){ 
     .... 
    res.json('success'); 
}],function(err){ 
    if(err) 
     console.log(err); 
}); 

} 




解決しよう: 最後に、私はPromisesを使用してチェーン非同期命令のための最高の読める解決策を見つけました。

apiRoutes.get('/endpoint', function(req, res){ 

    //Define 1st function 
    function actionOne(){ 
     return new Promise(function(fulfill, reject){ 
      myAsyncQueryFunction(err, result){ 
       if(err) { reject(err); } 
       else { fulfill(result); } 
      } 
     } 
    }; 

    //Define 2nd function 
    function actionTwo(){ 
     return new Promise(function(fulfill, reject){ 
      actionOne().then(function(result){ 
       my2ndQueryFun(err, result){ 
        if(err) { reject(err); } 
        else { fulfill(result); } 
       } 
      }, reject); 
     } 
    }; 

    //Execute async chained tasks, then send result to client 
    actionTwo().then(function(result){ 
     res.json(result); 
    }; 
} 

答えて

1

た場合は、何らかの理由により、index === array.length-1は、そのコールバック関数が呼び出されることはありませんでしょうので、あなたのコードがactionTwoで永遠に立ち往生され、真なることはありません。

また、照会している配列のインデックスに基づいてactionTwoコールバックを呼び出すタイミングを制御しているようです。しかし、それはエラーにつながる可能性があります。 connection.acquirecon.queryの両方が非同期であるため、最後のインデックスにあるということは、返す最後のクエリであるとは限りません。リストの最後の項目のクエリが実行するのが最速のクエリの場合はどうなりますか?問題はその後だった非同期メソッドconnection.acquireとcon.query、だった:

は、まず、すべてのSQLクエリタスクを宣言してから解決しようasync.parallelまたはasync.series

function actionTwo(list, callback){ 
    console.log("Action Two"); 


    var tasks = []; 

    list.forEach(function(item, index, array){ 
     item.arr = []; 
     tasks.push(async.apply(getDataFromSQL, item)); 
    }) 

    // could also be async.series(tasks, function (err, results) { 
    // it depends if you want to run the queries in parallel or not 
    async.parallel(tasks, function (err, results) { 
     if (err) { 
      console.log("Action Two Error") 
      return callback(err); 
     } 
     console.log("Action Two Success"); 
     return callback(null, results); //results is an array of the "cult" objects returned at each getDataFromSQL callback 
    }); 


    function getDataFromSQL(item, sqlCallback) { 
     // otherQuery = generate_query_based_on_item(item); 
     connection.acquire(function(err, con){ 
      con.query(otherQuery , function(err, result){ 
       con.release(); 
       if(err){ 
        console.log("SQL ERROR: "+err); 
        sqlCallback(err); 
       } else { 
        item.arr = result; 
        sqlCallback(null, cult); //not sure what cult meant. maybe result? 
       } 
      } 
     }); 
    } 
} 
+0

のような他のasync.js機能で自分の流れを制御することを検討します最初の呼び出しでは問題はありませんでしたが、2番目のSQL結果の前にメソッド全体が戻ってきたので、2番目のメソッドは実行時間がありませんでした。どうもありがとうございました! –

+0

他の非同期関数の使用を参照してください。私は各機能が彼の結果を次のものに渡す必要があるので、async.waterfallを使うことを選んだ。見て[ここ](http://stackoverflow.com/questions/9258603/what-is-the-difference-between-async-waterfall-and-async-series) –

関連する問題