我试图弄清楚为什么这段代码不起作用。我循环遍历依赖树(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
在上面的第二个链接中,接受的答案表明:
如果你异步填充数组,你应该获得该数组的承诺,并使用.then(Promise.all.bind(Promise))。如果你不知道什么时候停止添加承诺,那么这是不可能的,因为它们可能永远都不会得到解决。
但是我没有使用异步来填充数组。我需要这个吗?我在这里缺少什么?
由于我现在在.then()
以及.catch()
中都有错误记录,因此似乎出现了与内部发生的事情无关的错误。
在promiseFunction(deepObj[keys[j]]);
之前添加return语句打破了递归。我从迭代超过173个对象到68.添加捕获记录没有其他结果。上面的代码已更新,以分享更多的递归fn。当我运行它时,它似乎执行所有的承诺,但我无法知道这一点。我最关心的是知道1. promise.all的promise数组包含它应该包含的所有对象,以及2.捕获递归对象中所有对象的所有promise都被解析的时刻。
此外,对于记录,返回promise的这些函数中的每一个都必须是异步的。我已经多次回过头来试图简化并删除任何不必要的承诺。任务很复杂。必须执行一系列步骤,它们是异步的,并且它们是链接的,因为它们必须按特定顺序解析。
答案 0 :(得分:2)
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]]).length
为true
,那么您永远不会致电resolve
或reject
,以便承诺永远不会解决。
(请注意,调用promiseFunction
会递归地创建一个 new 承诺,该承诺永远不会放入Promise.all
)。
由于您的某些承诺无法解决,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
});
}
}
}
答案 1 :(得分:0)
让我们来看看你的promiseFunction
...
for (let j = 0; j < keys.length; j++) {
if (Object.keys(obj[keys[j]]).length) {
//if you get in here, promiseFunction returns undefined, and it never gets resolved
promiseFunction(obj[keys[j]]);
} else {
const dep = new Package(keys[j]);
console.log(`skan dep: ${keys[j]}`);
// and some more async hell that all resolves correctly
//but even if it resolves correctly, you still have the if...
}
}
要做到这一点,只需在if语句中返回promiseFunction
结果:
for (let j = 0; j < keys.length; j++) {
if (Object.keys(obj[keys[j]]).length) {
//if you get in here, you're saying this promise will depend on how this second promiseFunction will resolve
return promiseFunction(obj[keys[j]]);
} else {
//omitted for brevity...
resolve('your value');
}
}
现在,当你进入if语句时,你基本上是根据第二个promiseFunction
是否已经正确解决而告知解决的承诺 - 你将解决方案委托给另一个Promise。
我从来没有听过有人给它这个名字,但你可以把它想象成Promise递归:)