繁体   English   中英

Js:链接以清晰易读的方式承诺链接

[英]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();

因此,如果发生错误,则会同时rejres

从您的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM