【问题标题】:NodeJS - sum async results in recursive functionNodeJS - sum async 导致递归函数
【发布时间】:2017-04-20 01:15:53
【问题描述】:

您好,我有以下 python 递归函数,它对所有子节点的值求和,我想在 NodeJS 中移植,但异步调用有一些问题。

def getTree(parent_id, level=1):
    c.execute('select * from users where parent_id=?', (parent_id,))
    rows = c.fetchall()
    total = 0
    for child in children:
        total += getAsyncValue(child.id)
        total += getTree(child.id, level+1)
    return total

我尝试这样做,但我可能需要用 Promise 链接它,因为当我从异步函数中获取它时,总计数不可用

getTree = function(parent_id, level=1) {
  c.all("select * from users where parent_id="+parent_id, function(err, children) {
    var total = 0;
    children.forEach(function(child) {
      total += getAsyncValue(child.id)
      total += getTree(child.id, level+1)
    });
    return total;
  });
}

【问题讨论】:

  • 更容易移植此代码的一种方法是 ES2016+ async/await(这只是带有甜味的 Promises)- 仅使用 Promise(因此更好的浏览器兼容性)涉及更多

标签: javascript python asynchronous recursion promise


【解决方案1】:

没有看到 getAsyncValue 我无法提供完整的答案 - 但是

var getAsyncValue = function(id) {
    return new Promise((resolve, reject) => {
       // resolve some value some how
    });
};
// helper to make the getTree function "nicer"
c.allAsync = function(str) {
    return new Promise((resolve, reject) => 
        this.all(str, (err, children) => {
            if (err) {
                return reject(err);
            }
            resolve(children);
        })
    );
};
var getTree = function(parent_id, level=1) {
    return c.allAsync("select * from users where parent_id="+parent_id).then(children => 
        Promise.all(children.map(child => 
            Promise.all([getAsyncValue(child.id), getTree(child.id, level+1)])
            .then(([a, b]) => a + b)
        )).then(results => results.reduce((a, b) => a + b))
    );
};

认为使用async/await,代码可以写成:

var getAsyncValue = async function(id) {
    return new Promise((resolve, reject) => {
       // resolve some value some how
    });
};
// helper to make the getTree function "nicer"
c.allAsync = async function(str) {
    return new Promise((resolve, reject) => 
        this.all(str, (err, children) => {
            if (err) {
                return reject(err);
            }
            resolve(children);
        })
    );
};
var getTree = async function(parent_id, level=1) {
    let children = await c.allAsync("select * from users where parent_id="+parent_id);
    let total = 0;
    for (let i = 0; i < children.length; i++) {
        let child = children[i];
        total += await getAsyncValue(child.id);
        total += await getTree(child.id, level + 1);
    }
    return total;
};

【讨论】:

  • 好的,谢谢!我的问题是创建嵌套的 Promise.all 我认为没有使用 awaits 真的很冗长
猜你喜欢
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 2018-02-09
  • 2011-02-26
  • 1970-01-01
相关资源
最近更新 更多