2017-10-27 5 views
0

저는 Node JS의 초보자이고 NodeJS (v. 8.7.0), sqlite3 및 Express를 사용하고 있습니다.중첩 콜백간에 데이터를 전달하는 방법은 무엇입니까?

  • 릴리스 (ID, 제목, 이미지)
  • 링크 (ID, URL)

각 "해제"하나 이상을 가지고

나는 SQLite는 데이터베이스에 두 개의 테이블이 그것과 관련된 "링크".

dbh.all("SELECT * FROM releases ORDER BY id DESC", (err, rows) => { ... }) 

그리고 사용하여 주어진 자료에 대한 모든 링크를 얻을 수 있습니다 :

내가 사용하는 모든 자료를 얻을 수

dbh.all("SELECT * FROM links WHERE id = ?", (err, rows) => { ... }) 

을하지만 나는를 추가하는 방법을 알아낼 수 없습니다 "링크"속성을 각각의 "릴리즈"에 연결합니다.이 링크에는 해당 링크가 있으므로 결과 객체를 콧수염에 넘길 수 있고 HTML 페이지를 생성 할 수 있습니다.

관계형 데이터베이스 내부에 계층 적 데이터를 저장하는 것이 최선의 방법은 아니므로 PHP를 사용하여 쉽게이 작업을 수행 할 수 있지만 NodeJS를 사용하는 방법을 배우고 싶습니다.

이것은 내가 지금까지 왔어요 것입니다 :

var sqlite3 = require("sqlite3") 

function main() { 
    db = new sqlite3.Database("releases.sqlite3") 

    all = [] 

    db.each(
     "SELECT * FROM releases ORDER BY id DESC", 
     (err, release) => { 
      release.links = [] 
      db.all("SELECT url FROM links WHERE id = ?", [release.id], (err, links) => { 
       links = links.map((e) => { return e.url }) 

       release.links = links 

       // line above: tried 
       // links.forEach((e) => { release.links.push(e.url) }) 
       // too, but that didn't work either. 
      }) 
      all.push(release) 
     }, 
     (complete) => { console.log(all) } 
    ) 
} 

main() 

비록, 내가 그것을 실행할 때, 그것은 필연적으로 보여줍니다

links: [] 

때마다. 이 문제를 어떻게 해결할 수 있습니까?

미리 감사드립니다.

편집 1 :

이 SQL 조각 데이터베이스를 생성하고, 일부 데이터로 채 웁니다.

CREATE TABLE `links` (`id` TEXT, `url` TEXT); 
CREATE TABLE `releases` (`id` TEXT, `title` TEXT, `image` TEXT); 
INSERT INTO links VALUES 
('rel-001', 'https://example.com/mirror1'), 
('rel-001', 'https://example.com/mirror2'); 
INSERT INTO releases VALUES 
('rel-001', 'Release 001', 'https://example.com/image.jpg'); 

목표는이 같은 것입니다 : 두 쿼리가 콜백에서 console.log을 추가하여 실행되는 경우

{ 
    releases:[ 
     { 
     id:'rel-001', 
     title:'Release 001', 
     image:'https://example.com/image.jpg', 
     links:[ 
      'https://example.com/mirror1', 
      'https://example.com/mirror2' 
     ] 
     } 
    ] 
} 
+0

링크의 id 필드와 동일한 릴리스의 id 필드가 그대로 all를 초기화해야합니다? 하나의 열을 참조하는 별도의 열이 없습니까? 릴리스에 하나 이상의 링크가 있다고 가정 해보십시오.id 필드가 같으면 어떻게 될지 모르겠다. – dzm

답변

0

시도가 볼을, 또한 당신은 단지 두 번째 콜백 내에서 linkspush한다 콜백이 시작되기 전에 값이 존재하지 않으므로 빈 값을 푸시하려고 시도하고 release.links = []을 초기화 할 필요가 없으며 모든 쿼리가 실행 된 후에 만 ​​all이 채워 지므로 console.log(all);을 실행해야합니다. 마지막 자식 콜백에서 :

function main() { 
    all = [] 
    var parentComplete = false; 
    db.each("SELECT * FROM releases ORDER BY id DESC", (err, release) => { 
      db.all("SELECT url FROM links WHERE id = ?", [release.id], (err, links) => { 
       release.links = links.map(e => e.url); 
       all.push(release); 
       if (parentComplete){ 
        console.log(all); 
       } 
      }) 
     }, 
     (complete) => { 
      parentComplete = true; 
     } 
    ) 
} 

main(); 

p.s. 당신이 원하는 결과를 얻기 위해 당신은 객체 all = {releases:[]}

function main() { 
    all = {releases:[]}; 
    var parentComplete = false; 
    db.each("SELECT * FROM releases ORDER BY id DESC", (err, release) => { 
      db.all("SELECT url FROM links WHERE id = ?", [release.id], (err, links) => { 
       release.links = links.map(e => e.url); 
       all.releases.push(release); 
       if (parentComplete){ 
        console.log(all); 
       } 
      }) 
     }, 
     (complete) => { 
      parentComplete = true; 
     } 
    ) 
} 

main(); 
+0

쿼리가 실행되지만 결과는 인터리브되지 않습니다. 위의 코드를 실행하면, SELECT * FROM ORDER BY id DESC'의 결과가되고, 빈 배열이되고, 두 번째 쿼리가 실행됩니다. – Jetlef

+0

업데이트 된 코드를 시도하고 콘솔에서 두 쿼리의 결과를 가져 왔는지 확인하십시오. –

+0

변경된 사항이 없습니다. 질문을 편집 했으므로 직접해볼 수 있습니다. 그것은 매우 늦었고 머리가 두근 거려서 어리석은 뭔가를 놓친 것 같습니다 ... – Jetlef