2016-11-03 44 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