[英]Keeping Promise Chains Readable
我已經習慣了承諾鏈接數組。 當每個承諾是一個很長的行時,讀取一個承諾鏈是非常容易的
myArray.map(x => convertX)
.filter()
.whatever()
.etc()
這非常容易閱讀。 但是,當我使用自定義函數創建承諾鏈時,它會變得更加混亂。
database.query(first query)
.then(results => {
// do stuff
// do more
// even more
return database.query(second query)
})
.then(results => {
// rinse and repeat
})
.catch(err => {
// error handling
})
現在,這可以清晰,但當承諾鏈進一步延伸時,它會變得有點多。 如果我使每個承諾都是它自己的功能,那么我可以簡化流程,所以代碼看起來像這樣(imo,1000x更易讀)。
db.query(first query)
.then(storeFirstQuery)
.then(secondQueryAndStoreIt)
.then(thirdQueryAndStoreIt)
.catch(errHandlingFunction)
這樣,我可以重新排列函數,而無需操縱從一個promise傳遞到下一個promise的值。 如果一個承諾使用了另一個的結果,它只需要在另一個之后,而不是緊接在另一個之后。 這樣我就可以在任何需要的地方偷偷兌現承諾。
但是,這需要我的promise鏈使用每個promise的范圍之外的變量。 有沒有一種經過驗證的方法來做到這一點?
編輯 - 似乎async
/ await
是執行此操作的最佳方法,但我在Heroku上運行Node並且它尚不支持:/
好吧,你可以使用承諾這樣的東西:
myArray.map(x => convertX)
.filter()
.whatever()
.etc()
如果你從npm使用我的rsp模塊。
除此之外,您可以使用ES2017的async
/ await
功能來簡化承諾鏈,尤其是它們的范圍。
因為代碼如下:
db.query(first query)
.then(storeFirstQuery)
.then(secondQueryAndStoreIt)
.then(thirdQueryAndStoreIt)
.catch(errHandlingFunction)
如果您需要在最后的thirdQueryAndStoreIt()
處理程序中使用第一個查詢的結果,則訪問超出范圍的數據時會遇到問題。 但是當你這樣做時:
try {
let a = await db.query(first query);
let b = await storeFirstQuery();
let c = await secondQueryAndStoreIt();
let d = await thirdQueryAndStoreIt(a); // use 'a' here
} catch (e) {
errHandlingFunction(e);
}
然后你沒有范圍問題,因為你可以輕松訪問所有以前分配的變量。
有關支持此語法的節點版本,請參閱此內容:
您可以使用節點V7.6使用+開箱或節點V7.0 +與--harmony
標志。
對於較舊的Node版本,您可以使用co或Bluebird.coroutine使用生成器函數和yield
而不是await
來獲得類似的語法。
如果你真的想要,可以通過自己創建范圍將范圍限制為單個元承諾:
return new Promise((resolve, reject) => {
const f1 = () => { /* ... */ };
const f2 = () => { /* ... */ };
const f3 = () => { /* ... */ };
return db.query()
.then(f1)
.then(f2)
.then(f3)
.then(resolve)
.catch(reject);
});
但最明顯的方法是使用async
/ await
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.