[英]Js : Chaining promises chains in a clear and readable way
您好,有溢水者,
我目前正在使用带有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)=>{})
代码中有不同的部分无法正常工作,或者不应以这种方式编写。
如果您使用这样的快捷方式:
err && rej(err);
res();
您应该了解它们的含义,因为这等于:
if( err ) {
rej(err);
}
res();
因此,如果发生错误,则会同时rej
和res
。
从您的popUser
返回承诺的数组,所以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
进行相同操作, 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)
}
猫鼬回调是旧版API。 猫鼬支持诺言很长一段时间,不需要被承诺。
对于并发的Promise, forEach
可以用map
代替,这是后者的确切用例:
function popUser(users){
return Promise.all(
users.map(userData => new User(userData).save())
);
}
async..await
可以在promise应该是顺序的其余情况下使用:
try {
await popUser(users);
await popClasses();
...
} catch (err) {
...
}
为什么不返回Promise.all(chain)
函数中的popUser
Promise.all(chain)
。
返回Promise更好地匹配popUser
语义,后者是异步执行的功能。返回promise数组会造成混淆。
然后,您可以使用popUsers.then(popClasses).then(...). ... .catch((err)=>{})
popUsers.then(popClasses).then(...). ... .catch((err)=>{})
来排队诺言
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.