2016-11-03 11 views
0

私の問題を解決しない同様の質問hereがありました。私は最初にカテゴリを取得し、次にカテゴリに基づいて、各カテゴリの情報を見つけることができる10時間ごとにcronジョブを実行しようとしています。どうすれば下のPromiseを簡略化できますか?私はBluebirdまたはQを使用していません。これはネイティブJSの約束です。同じコールバック地獄の約束を避けるようになっていたように正直なところ、以下のコードは、あなただけの.then()のためにインデントの余分なレベルの使用を停止する場合は、あなたは非常に単純な構造を持って、任意の提案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()ハンドラ 含まif()声明 この修正版では別の非同期操作

が含まれているループ 、半分あなたのインデントが約束とは何の関係もありませんあなたの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()も非同期であると約束を返した場合、あなたはおそらくあまりにも約束鎖にそれらをフックしたいです。あなたはすべての結果(あなたのタイトルが意味する何かが、あなたの質問doesnのを収集しようとしている場合

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がすべてが完了しているかどうかを確認せずに解決すれば、 – PirateApp

+1

@PirateApp - 最後の2つのコードブロックのどちらかが動作すると、約束の拒否が捕まえられ、それが 'Promise.all()'に到達する前に処理されます問題ない。あなたが '.catch()'ハンドラを持っていて、拒否された約束を返さなかったり、その中から捨てられなかった場合、拒否された約束は "処理された"とみなされ、状態は解決済みに変わります。最後の2人は両方とも内部の '.catch()'を記録するので、 'Promise.all()'は解決された約束しか見ることができません。あなたは大丈夫です。 – jfriend00

関連する問題