javascript - 动态填充 Promise.all()

标签 javascript asynchronous promise

我想弄清楚为什么这段代码不起作用。我正在遍历依赖树 (deepObject),对于每个我想运行的函数都返回一个 promise 。然后我希望下一组功能在所有 promise 解决后发生,但 promise.all 中的控制台日志没有执行。 ES6 也很酷,如果你有更好的方法,但我也很想知道为什么这段代码不起作用。

已更新以添加 .catch(这没有效果)

for (let i = 0; i < keys.length; i++) {
    promisesArray.push(promiseFunction(deepObject[keys[i]]));
}
Promise.all(promisesArray).then(resolved => {
    console.log('dep promises resolved');
    console.log(`resolved: ${JSON.stringify(resolved)}`);
}).catch(err => console.error(new Error(err));

// promiseFunction is recursive
promiseFunction(obj) {
    return new Promise((resolve, reject) => {

        const keys = Object.keys(deepObj);
        for (let j = 0; j < keys.length; j++) {
            if (Object.keys(deepObj[keys[j]]).length) {
                // adding return statement to following line breaks it
                // that was already recommended, see threads
                promiseFunction(deepObj[keys[j]]);
            } else {
                const dep = new Package(keys[j]);
                console.log(`skan dep: ${keys[j]}`);
                dep.fetch().then(() => {
                    return anotherFunction();
                }).then(() => {
                    return Promise.all([
                        promise1(),
                        promise2(),
                        promise3(),
                    ]).then(resolved => {
                        if (resolved[0].propertyINeed) {
                            resolve(true);
                        }
                        resolve(false);
                    });
                }).catch(err => {
                    console.error(new Error(err));
                    process.exit(1);
                });
            }
        }
    });

我知道这段对话 - has been discussed - on here before

在接受的答案上方的第二个链接中建议:

In case you are asynchronously filling the array, you should get a promise for that array, and use .then(Promise.all.bind(Promise)). If you don't know when you stop adding promises, this is impossible anyway as they might never all be resolved at all.

但是我没有使用异步来填充数组。我需要这个吗?我在这里缺少什么?

更新

由于我现在在 .then().catch() 中都有错误记录,所以似乎出现了与内部发生的事情无关的错误

promiseFunction(deepObj[keys[j]]); 之前添加 return 语句破坏了递归。我从迭代 173 个对象到 68 个对象。添加 catch 没有记录额外的结果。上面的代码已更新以共享更多递归 fn。当我运行它时,它似乎执行了所有的 promise ,但我无从知晓。我最关心的是知道 1. promise.all 的 promise 数组包含它应该包含的所有对象,以及 2. 捕获递归对象内所有对象的所有这些 promise 都已解决的时刻。

另外,郑重声明,这些返回 promise 的函数中的每一个都必须是异步的。我已经多次回顾所有这些,试图简化和删除任何不必要的 promise 。任务很复杂。有一系列必须执行的步骤,它们是异步的,并且它们是链式的,因为它们必须按特定顺序解析。

最佳答案

if (Object.keys(obj[keys[j]]).length) {
    promiseFunction(obj[keys[j]]);
} else {
    // and some more async hell that all resolves correctly

如果 Object.keys(obj[keys[j]]).lengthtrue 那么你永远不会调用 resolve reject 所以 promise 永远不会解决。

(请注意,调用 promiseFunction 会递归地创建一个 promise,它永远不会放入 Promise.all 中)。

由于您的一些 promise 没有解决,Promise.all 也不会。


你可能需要更多的东西:

var promises = [];
processObject(obj);
Promise.all(promises).then(etc etc);

function processObject(object) {
    for ( loop; over; object ) {
        if (condition) {
             processObject(object[something]);
        } else {
             promises.push(new Promise( (res, rej) => {
                 // so something async
             });
        }
    }
}

关于javascript - 动态填充 Promise.all(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50794503/

相关文章:

javascript - Meteor.js 安全地嵌入 iframe

javascript - Bootstrap div 背景图像

asp.net - Microsoft Azure .NET SDK 异步同步

angular - 使用异步管道从可观察对象中读取对象字段

javascript - AngularJs $q.defer() 不工作

javascript - 我怎么能中止 JavaScript Promise?

javascript - 为什么JS是解释型的而不是编译型的?

javascript - html 表单提交不会在元素中永久显示来自 javascript 的结果

javascript - 使用 RxJS 如何缓冲函数调用,直到另一个异步函数调用已解决

javascript - 无法使用 promise 命令 js 函数执行