2017-10-23 6 views
3

저는 노드 세계에 익숙하지 않고 php 애플리케이션을 노드로 마이그레이션하려고합니다. 모든 기사 데이터를 반환하려면 첫 번째 쿼리의 결과에 따라 여러 가지 다른 쿼리를 수행해야합니다. 현재 내 데이터 개체는 두 쿼리가 실행되기 전에 반환되므로 비어 있습니다. 약속 기반 접근 방식을 사용하여 어떻게 이러한 쿼리를 "연결"할 수 있습니까?Node + 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 쿼리를 단일 쿼리로 쉽게 결합 할 수 있습니다. 이것은 두 가지 작업을 수행하는 것보다 훨씬 효율적입니다. 이것이 당신이 사용하기를 바라는 나머지 검색어와 관련이 있는지는 확실치 않지만,주의해야 할 점은 확실합니다.
+0

안녕하세요. Derek, 신속한 답장을 보내 주셔서 감사합니다. 지금 당장 귀하의 솔루션을 구현하려고 노력할 것이고 그것이 효과가 있었다면 알려 드리겠습니다. 나는 https://github.com/mysqljs/mysql에서 구문을 복사했고 connection.query 내에 함수를 사용했다. 첫 번째 쿼리의 값이 필요하므로 이러한 쿼리를 결합 할 수있는 방법이 있는지 모르겠습니다. 나머지 쿼리는 내 코드의 쿼리와 비슷하지만 첫 번째 쿼리의 결과에 따라 해당 쿼리 중 하나만 실행됩니다. 예를 들어, article type이 listicle query 2 일 때 기사가 후원 이야기 쿼리 3 인 경우 실행됩니다. – Menelik

+0

@Menelik 1) 나중에 쿼리가 첫 번째 쿼리의 데이터에 의존하면 변수를 저장하는 것은 끔찍한 생각이 아닙니다. 2) 조건부 쿼리를이 방식으로도 쉽게 실행할 수 있습니다. –

+0

코드를 가지고 놀아봤을 때 다음과 같은 오류 메시지가 나타납니다. (예 : Promise.then() => {if (cond) {return connection.query()} else {return connection.query()}} : TypeError : connection.query (...). 그러면 함수가 아닙니다 .'이 작업을 수행하려면 특정 약속 라이브러리를 가져와야합니까? – Menelik