【问题标题】:Typescript recursion of promises承诺的打字稿递归
【发布时间】:2021-07-04 20:34:26
【问题描述】:

我需要在一个相互依赖的数据库上运行多个查询(在第二个查询之前,我需要第一个查询的结果等)。 数据库描述了一个文件夹结构,因此调用模式是一个树状结构(首先是根,然后是分支等)。 在继续编写代码之前,我想保证所有查询都已完成。查询(sqlite3)是异步的。

这是一个(非工作)虚拟代码,用于建模这些东西。我用 setTimeout() 函数替换了查询。

var array: Array<Number> = [];

const f = (iDepth: number): Array<Promise<any>> => {
    const pa = [];

    array.push(iDepth);
    if (iDepth > 1) {
        for (var i = 0; i < 2; i++) {
            pa.push(
                new Promise((resolve) => {
                    setTimeout(() => {
                        Promise.all(f(iDepth - 1)).then((prom) => {
                            return prom;
                        });
                    }, 1);

                    //return resolve(f(iDepth-1));
                })
            );
        }
    } else {
        return [Promise.resolve()];
    }

    console.log(pa);
    return pa;
};

Promise.all(f(4)).then(() => {
    console.log("***");
    console.log(array);
});

错误在哪里? 请注意,我是 TS 菜鸟。

【问题讨论】:

  • 错误是什么?你想做什么?您正在遍历的数据的形状是什么? “我用 setTimeout() 函数替换了查询。”请注意,这通常是个坏主意,因为 setTimeout 不会返回承诺。而且你也永远不会履行你的诺言。
  • 你能显示实际的代码吗?目前还不清楚这些查询如何相互依赖。如果每个都依赖于前一个的结果,并且它们按顺序运行,那么您不应该在任何地方构建一组承诺(或使用Promise.all)。
  • 嗨,实际代码非常混乱,这就是我编写这个虚拟代码的原因。数据库查询是 sqlite3 的,例如 each() 和其他类似函数(github.com/mapbox/node-sqlite3/wiki/API)并使用 setTimeout() 之类的回调,这就是我用它替换东西的原因。但是,如果我可以强制所有事情同步工作对我来说是可以的。 @Bergi 这就是我使用 Promise.all() 的原因。
  • 那么请尝试将 sqlite 的东西重构为一个辅助函数(然后您可以使用 setTimeout 模拟它),但是您仍然需要向我们展示您传递给这个辅助函数的数据是什么来自上一个查询结果。

标签: typescript recursion promise


【解决方案1】:

这似乎是一个可行的解决方案:将带有回调的函数转换为 Promise。我只处理了快乐的道路(解决)。

var array:Array<Number> = [];

const f = (iDepth:number):Array<Promise<any>> => {
    const pa = [];

    array.push(iDepth);
    if (iDepth > 1) {
        for (var i = 0; i < 2; i++) {
            pa.push(new Promise((resolve) =>{
                setTimeout(() => {
                    return resolve(Promise.all(f(iDepth-1)));
                }, 100);
            }));
        }
    }
    return pa;
};

Promise.all(f(4)).then(() => {
    console.log('***Finished***')
    console.log(array);
})

请注意,我仍然不确定在概念层面上这是一个很好的解决方案,或者专业的前端会以不同的方式处理整个事情。

另外请注意,我可以删除内部选择器的 else 分支,并且仍然可以工作。

【讨论】:

  • PS 还请注意,我觉得在第 11 行非常随意地使用了“解决”这个词。但是有效。
猜你喜欢
  • 1970-01-01
  • 2020-03-10
  • 2018-12-19
  • 2019-08-24
  • 1970-01-01
  • 1970-01-01
  • 2017-04-21
  • 2018-02-04
  • 1970-01-01
相关资源
最近更新 更多