使用Promise表行走/递归

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Promise表行走/递归相关的知识,希望对你有一定的参考价值。

我想使用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

答案

我不明白为什么你想得到一堆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
  )
);
另一答案

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

以上是关于使用Promise表行走/递归的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段12——JavaScript的Promise对象

前端面试题之手写promise

js的promise如何递归调用?

Node.js / Javascript 多重递归承诺在视图中返回

如何使用 Promise Kit 调用递归函数?

将递归异步函数转换为 Promise