[英]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.