使用Promise表行走/递归

时间:2017-12-29 18:04:00

标签: javascript node.js asynchronous promise synchronization

我想使用Promises来遍历数据库表,以便同步获取每个步骤的数据。我认为我的代码应该类似于:

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);
}

此代码的问题在于循环立即迭代而不等待then()完成。

this answer中,海报建议使用Promise.race()或完全放弃Promise以支持async

2 个答案:

答案 0 :(得分:2)

可以使用async / 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);

答案 1 :(得分:0)

我不明白为什么你想获得一堆id但却没有对结果做任何事情。您的原始功能几乎就在那里但是如果出现问题,您应该拒绝错误和结果到目前为止。

如果一切顺利,请解决所有结果:

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
  )
);