嵌套的 promise,然后在第一个 promise 节点之前运行



当我在承诺的 .then 中运行承诺时,我的程序遇到了问题,但是它在第一个承诺之前运行第二个承诺。这不是我想要的,因为它依赖于第一个承诺来工作。这是我的代码(console.logs 是随机的,但我只是当场想出了东西来检查事情何时运行)

new Promise((resolve, reject) => {
for (i = 0; i < 10; i++) {
var query = {
class: result[`class${i}`]
};
dbo.collection("homeworks").find(query).toArray(function(err, result) {
if (err) throw err;
for (i = 0; i < result.length; i++) {
current = current + 1;
console.log(current)
allhomework[current] = result[i];
console.log(allhomework[current])
}
db.close();
});
}
console.log("HOLA");
resolve(allhomework);
})
.then((allhomework) => {
console.log("HOLA MIS AMIGOS")
new Promise((resolve, reject) => {
console.log("v");
for (i = 0; i < 10; i++) {
console.log("uaefshiudvhofdh")
console.log(allhomework[1]);
}
resolve();
}).then(() => {
response.render('index', {
username: req.session.user,
homeworks: allhomework
});
})
})
.catch(console.log)

解决这个问题的最佳方法是使用数据库的 promise 接口,并使用Promise.all()来跟踪循环中的所有异步数据库操作何时完成。 但是,如果您想使用现有循环手动编码,则只需保留一个计数器以备不时完成。

new Promise((resolve, reject) => {
let cntr = 10;
for (let i = 0; i < 10; i++) {
var query = {
class: result[`class${i}`]
};
dbo.collection("homeworks").find(query).toArray(function(err, result) {
if (err) {
db.close();
return reject(err);
}
for (let i = 0; i < result.length; i++) {
current = current + 1;
console.log(current)
allhomework[current] = result[i];
console.log(allhomework[current])
}
--cntr;
if (cntr === 0) {
db.close();
resolve(allHomework);
}
});
}
console.log("HOLA");
});

有关此代码的其他说明:

我也想知道为什么在你的外循环中间有一个db.close()。 我认为这会引起问题。

我还在您的if (err)支票中添加了一个reject(err)

您与i变量存在循环冲突。 为每个字母放置一个let,使它们分开或将其中一个更改为不同的字母。


下面是在数据库中使用 promise 接口的版本。 我能够完全摆脱内部循环,只是让承诺收集所有结果,以便为我们排序。 Monbodb 的.toArray()返回一个承诺,如果您不向它传递回调,该承诺将随着查询结果进行解析。 我们可以将其与Promise.all()一起使用,按顺序收集所有结果,并告诉我们何时完成所有结果:

let promises = [];
for (let i = 0; i < 10; i++) {
let query = {
class: result[`class${i}`]
};
promises.push(dbo.collection("homeworks").find(query).toArray());
}
Promise.all(promises).then(allResults => {
// flatten the results into all one array - promises will have kept them in proper order
db.close();
let results = [].concat(...allResults);
// now do whatever you want with the final array of results
}).catch(err => {
db.close();
// handle error here
});

最新更新