您好,有溢水口
我目前正在使用带有mongo数据存储的节点服务器来开发我的项目。我目前正在编写一些函数来为我填充数据库。
数据库中对象的示例包括“用户”,“班级”,“学年”,“学生评分”等。
创建此类对象的所有功能都是这样实现的:
function popUser(users){
chain = [];
users.forEach((v,i,a)=>{
let p = new Promise(function(res,rej){
let newU = new User(v);
newU.save(()=>{
err && rej(err);
res();
});
});
chain.push(p);
});
return chain
}
在我的填充模块的其余部分中,我会根据需要调用此类函数。调用上述函数的顺序很重要,因此我不希望完全并行执行构造函数。
有了Promises,我可以做这样的事情:
popUser(users).then(popClasses).then(...). ... .catch((err)=>{})
有了Promises Chains,我知道我可以做到以下
Promise.all(usersChain).then(()=>{
//make a new chain for Classes
Promise.all(classesChain).then (()=>{},(err)=>{})
},(err)=>{})
我认为我们可以同意,它变得很难阅读和理解,因此这个问题:
是否有一种方法可以使用更易读的不同语法来实现相同的结果?
编辑:更清楚地说,usersChain和cleassesChains是Promises数组,用于创建一些对象(一个或多个)并将其插入数据库。 我无法创建单个链,因为某些对象可能已经插入,而某些对象可能必须插入。
编辑:等等,我可以打电话给
Promsie.all(populateCountersPromise).then(promise1).then(promise2).catch((err)=>{})
答案 0 :(得分:0)
代码中有不同的部分无法正常工作,或者不应以这种方式编写。
如果您使用这样的快捷方式:
err && rej(err);
res();
您应该知道它们的意思,因为它等于:
if( err ) {
rej(err);
}
res();
因此,如果发生错误,将同时调用rej
和res
。
从您的popUser
返回一个Promises数组,所以popUser(users).then(popClasses)
会失败,因为您无法在该数组上调用.then
。
您应该做的第一件事就是清理popUser
函数:
function popUser(users) {
let promises = users.map((v, i, a) => {
return new Promise(function(res, rej) {
let newU = new User(v);
newU.save(err => {
if (err) {
rej(err)
} else {
res()
}
});
});
});
return Promies.all(promises)
}
使用.map
代替forEach
和push
,因为它使您从一开始就很清楚。并使用Promies.all
从函数中返回一个Promise,等待所有用户被保存,如果对popClasses
做同样的操作,则可以这样写:
popUser(users)
.then(popClasses)
.then(...)
.catch((err)=>{})
如果您真的想像上一个代码片段一样编写它,则将其更改为:
Promise.all(usersChain)
.then(() => Promise.all(classesChain))
.then(() => {})
.catch(err => {})
当今,许多API都支持经典回调和Promises,因此您可以进一步改善popUser
:
function popUser(users) {
let promises = users.map(v => new User(v).save())
return Promies.all(promises)
}
答案 1 :(得分:0)
猫鼬回调是旧版API。猫鼬支持承诺很长一段时间,不需要被承诺。
对于并发承诺,forEach
可以替换为map
,这是后者的确切用例:
function popUser(users){
return Promise.all(
users.map(userData => new User(userData).save())
);
}
async..await
可以在其他应许应按顺序进行的情况下使用:
try {
await popUser(users);
await popClasses();
...
} catch (err) {
...
}
答案 2 :(得分:0)
为什么不在函数Promise.all(chain)
中返回popUser
。
返回承诺最好与popUser
的语义相匹配,这是异步执行的功能。返回promise数组会造成混淆。
然后您可以使用popUsers.then(popClasses).then(...). ... .catch((err)=>{})
将诺言排队