我在我的程序中遇到问题,我在承诺的.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)
答案 0 :(得分:2)
嗯,解决此问题的最佳方法是使用数据库的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()
。我认为这会引起问题。
我还在reject(err)
支票上添加了if (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
});