$ q.all承诺取决于另一个承诺的结果

时间:2015-12-29 22:07:05

标签: javascript angularjs

我目前有三个嵌套的承诺,我想转成$ q.all调用。

它看起来像这样。

ds.saveData(data).then(function (result1){
    someOtherVar = result1.Id;
    ds.saveSomethingDependant(someOtherData).then(function (result2){
        ds.saveAThirdThing(someOtherVar).then(function (result3){
            ns.notify();
        }, function (error){
            ns.error(error);
        });
    }, function (error){
        ns.error(error);
    });
}, function (error) {
    ns.error(error);
});
哇哇呀呀。我担心的是我编辑someOtherVar的地方。还有其他方法可以做到这一点,所以我没有嵌套的承诺,但仍然在一个承诺后编辑数据?嵌套的承诺是进行茉莉花测试的噩梦。

谢谢!

2 个答案:

答案 0 :(得分:3)

由于result2依赖于result1,因此在执行前者之前,您必须等到后者准备就绪。但是,如果第一个和第三个操作不相互依赖,您仍然可以使用$q.all

$q.all({
  saveData: ds.saveData,
  saveAThirdThing: ds.saveAThirdThing
}).then(function(results) {
  /* expect(results).toEqual({
   *   saveData: result1,
   *   saveAThirdThing: result3
   * });
   */
  return saveSomethingDependent(results.saveData.Id);
}).then(function(result2) {
  // all done
  ns.notify();
}, function(error) {
  // something in the chain above failed
  ns.error(error);
});

我们正在利用这样一个事实:您可以从解析处理程序返回一个promise,然后解析该promise将其发送到链中的下一个promise(从而避免嵌套)。

您也可以通过将拒绝处理程序放在链的末尾来进行一些简化,因为您在示例中以相同的方式处理所有错误。

答案 1 :(得分:3)

让我们说方便易读的方法链

var saveDate = function(data) {
  return ds.saveDate(data);
}

var saveOtherthings = function(result) {
  return $q.all([ds.saveSomethingDependant(result.id), ds.saveAThirdThing(result.id)])

}

saveDate(data)
  .then(saveOtherthings)
  .then(function(result) {
    ns.notify();
  }, function(error) {
    ns.error(error);
  });