簡體   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