2017-12-29 13 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

이해가 안 . 원래 함수가 거의있었습니다.하지만 문제가 발생하면 오류와 결과를 거부해야합니다.

그리고 모든것이 제대로가는 경우 모든 결과에 해결 :

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

감사합니다. 간접적 인 재귀 접근 방식이 저에게 효과적입니다. –

관련 문제