簡體   English   中英

保持承諾鏈可讀

[英]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版本,您可以使用coBluebird.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM