2017-10-23 9 views
3

私はノードの世界ではかなり新しく、PHPアプリケーションをノードに移行しようとしています。すべての記事データを返すには、最初のクエリの結果に応じていくつかの異なるクエリを実行する必要があります。現在、私のデータオブジェクトは2つのクエリが実行される前に返されるので空です。約束されたベースのアプローチを使用してこれらのクエリを「チェーン化」する方法を教えてください。ノード+ Mysql:別のクエリに基づいてより多くのクエリを実行するには

ライブラリhttps://github.com/lukeb-uk/node-promise-mysqlが見つかりましたが、私のコードでどのように実装するのか分かりません。

exports.getArticleData = function(req, done) { 
    pool.getConnection(function(error, connection) { 
    if (error) throw error; 

    var data = { 
     article: {}, 
     listicles: [] 
    }; 

    // Inital query 
    connection.query(
     `SELECT article_id, title, is_listicle_article, FROM com_magazine_articles AS article WHERE article_id = ${req 
      .params.articleId}`, 
     function(error, results) { 
      data.article = results; 
     } 
    ); 

    // This query should only be excuted if is_listicle_article = true 
    if (data.article.is_listicle_article) { 
     connection.query(
      `SELECT * FROM com_magazine_article_listicles WHERE article_id = ${req.params 
       .articleId}`, 
      function(error, results) { 
       data.listicle = results; 
      } 
     ); 
    } 

    // More queries depending on the result of the first one 
    // .... 
    // .... 

    // Callback with the data object 
    done(data); 

    connection.release(); 
    }); 
}; 

他のクエリ結果に基づいてクエリを実行する最良の方法は何でしょうか?どんな助けでも本当に感謝しています。

答えて

1

あなたが探している機能はPromise chainingです。これは、以前の値の結果に応じて、一連の約束事を構成することができます。あなたのコードにこれを適用すると、あなたはこのような何かを得るでしょう:

exports.getArticleData = function(req, done) { 
 
    pool.getConnection(function(error, connection) { 
 
    if (error) throw error; 
 

 
    // Inital query 
 
    return connection.query(
 
     `SELECT article_id, title, is_listicle_article, FROM com_magazine_articles AS article WHERE article_id = ${req 
 
      .params.articleId}` 
 
    ).then((rows) => { 
 
    
 
     return Promise.all(rows.map((article) => { 
 
      if (article.is_listicle_article) { 
 
      return connection.query(
 
       `SELECT * FROM com_magazine_article_listicles WHERE article_id = ${req.params 
 
        .articleId}` 
 
      ); 
 
      } else { 
 
      return Promise.resolve(null); 
 
      } 
 
     })); 
 
    }).then((res) => { 
 
    connection.release(); 
 
    done(res.filter(function(i){ return i != null; })); 
 
    }) 
 

 
    // This query should only be excuted if is_listicle_article = true 
 
    
 

 
    // More queries depending on the result of the first one 
 
    // .... 
 
    // .... 
 

 
    // Callback with the data object 
 
    connection.release(); 
 
    }); 
 
};

を明らかに私はあなたのコードのすべてを持っていないので、私はこの例を確認できませんでしたが、これはする必要がありますおおよそあなたが探している機能です。

  • connection.query()は約束を(別名コールバック関数を必要としない)を返します。それは、私はあなたがあなたのコード例に気を付ける必要がありますミスのカップルがあったと思う、と述べました。この機能を使用すると、コードがきれいになります。
  • connection.query()は、単一の値ではなく、行の配列を返します。これはあなたのサンプルコードでは無視されたようです。
  • 約束事を使うときに変数に物事を保存しないようにしてください。それは必要ありません。この問題を解決するには、Promise API(Promise.resolve()、Promise.reject()、Promise.any()、Promise.catch()、Promise.all()など)を参照してください。
  • SQL問合せは、単一の問合せに簡単に結合できます。これは、2つの操作を実行するより効率的になります。これがあなたが使用したいと思っている残りのクエリーのケースであるかどうかは確かではありませんが、間違いなく目を引くものがあります。
+0

こんにちはデレク、迅速な返信をありがとうございます。私はすぐにあなたのソリューションを実装しようとし、それが働いた場合にお知らせします。私はhttps://github.com/mysqljs/mysqlの構文をコピーし、connection.query内で関数を使用しました。最初のクエリの値が必要なので、これらのクエリを組み合わせる方法があるかどうかはわかりません。残りのクエリは自分のコードと似ていますが、最初のクエリの結果に応じてこれらのクエリのうちの1つだけが実行されます。たとえば、article typeがlisticle query 2である場合、記事がスポンサーのstory query 3の場合に実行されます。 – Menelik

+0

@Menelik 1)後のクエリが最初のクエリのデータに依存する場合、変数の格納はひどい考えではありません。 2)このように条件付きクエリを簡単に実行することもできます。 –

+0

あなたのコードで遊んだだけで、次のようなエラーが表示されます。 : 'TypeError:connection.query(...)。それでは関数ではありません.'これを動作させるには、特定の約束ライブラリをインポートする必要がありますか? – Menelik

関連する問題