2016-11-03 89 views
0

我看到了類似的問題here其犯規解決我的問題。我試圖每10小時運行一次cron作業,讓我先獲得類別,然後根據類別,找到每個類別的信息。我如何簡化下面的Promise。我不使用藍鳥或Q,這是本地JS承諾。老實說,下面的代碼看起來像同回調地獄承諾都應該避免,有什麼建議我怎樣才能返回承諾數組從then子句

flipkart.getAllOffers = function() { 
    interval(43200,() => { 
     flipkart.findAllCategories() 
      .then((categories) => { 
       flipkart.save('flipkart_categories.json', categories) 
       if (categories) { 
        for (let item of categories) { 
         flipkart.findAllForCategory(item.category, item.top) 
          .then((items) => { 
           flipkart.save('flipkart_top_' + item.category + '.json', items) 
          }).catch((error) => { 
           console.log(error) 
          }) 
        } 
       } 
      }) 
      .catch((error) => { 
       console.log(error) 
      }) 
    }) 
} 

function interval(seconds, callback) { 
    callback(); 
    return setInterval(callback, seconds * 1000); 
} 
+1

首先,你使用了比需要更多的縮進。通過將'.then()'處理程序放在另一個縮進級別,您將累積更多縮進量。這是一種個人風格的東西,但不是必需的,並且創建比簡單閱讀代碼所需的更多縮進。 – jfriend00

回答

1

如果停止使用縮進一層額外的只是.then(),那麼你有一個非常簡單的結構。

一個.then()處理器包含 的if()聲明 包含一個for循環 包含另一個異步操作

在這個修改後的版本,有一半的縮進來自你iffor具有無關的承諾。其餘的對我來說似乎很合乎邏輯,完全不像回撥地獄。這是實現你所顯示的邏輯所需要的。

flipkart.getAllOffers = function() { 
    interval(43200,() => { 
     flipkart.findAllCategories().then((categories) => { 
      flipkart.save('flipkart_categories.json', categories) 
      if (categories) { 
       for (let item of categories) { 
        flipkart.findAllForCategory(item.category, item.top).then((items) => { 
         flipkart.save('flipkart_top_' + item.category + '.json', items) 
        }).catch((error) => { 
         console.log(error) 
         throw error;  // don't eat error, rethrow it after logging 
        }); 
       } 
      } 
     }).catch((error) => { 
      console.log(error) 
     }) 
    }) 
} 

如果flipkart.save()也是異步,並返回一個承諾,那麼你可能要掛鉤到這些承諾過於鏈。


你總是可以創建一個可以改善一下也是這樣的一個輔助功能:

flipkart.getAllOffers = function() { 
    interval(43200,() => { 
     flipkart.findAllCategories().then(iterateCategories).catch((error) => { 
      console.log(error); 
     }) 
    }) 
} 

function iterateCategories(categories) { 
    flipkart.save('flipkart_categories.json', categories); 
    if (categories) { 
     for (let item of categories) { 
      flipkart.findAllForCategory(item.category, item.top).then((items) => { 
       flipkart.save('flipkart_top_' + item.category + '.json', items); 
      }).catch((error) => { 
       console.log(error); 
      }); 
     } 
    }  
} 

如果你想收集所有的結果(什麼你的標題所暗示的,但你的問題沒有按實際上不提),那麼你可以這樣做:

flipkart.getAllOffers = function() { 
    interval(43200,() => { 
     flipkart.findAllCategories().then(iterateCategories).then((results) => { 
      // all results here 
     }).catch((error) => { 
      console.log(error); 
     }); 
    }) 
} 

function iterateCategories(categories) { 
    flipkart.save('flipkart_categories.json', categories); 
    let promises = []; 
    if (categories) { 
     for (let item of categories) { 
      let p = flipkart.findAllForCategory(item.category, item.top).then((items) => { 
       flipkart.save('flipkart_top_' + item.category + '.json', items); 
      }).catch((error) => { 
       console.log(error); 
      }); 
      promises.push(p); 
     } 
    } 
    // return promise here that collects all the other promises 
    return Promise.all(promises); 
} 
+1

添加了更多的版本來顯示不同的編碼風格,並顯示收集所有結果。 – jfriend00

+0

非常感謝你的所有您的建議,我將無法使用Promise.all因爲其中一些如果URL過期和Promise.any根本沒有解決,如果所有都做了,無極檢查有時可能會失敗。從藍鳥解決似乎並沒有出現在本地es6承諾:) – PirateApp

+1

@PirateApp - 最後兩個代碼塊的方式工作,任何承諾拒絕被捕獲並處理之前它得到'Promise.all()'這樣沒什麼大不了。如果你有一個'.catch()'處理程序,並且你不返回被拒絕的承諾或從其中拋出,那麼被拒絕的承諾將被視爲「已處理」,並且狀態更改爲已解決。既然最後兩個都有內部的'.catch()'記錄它並且不會重新拋出,'Promise.all()'只會看到已解決的promise。你應該沒問題。 – jfriend00