简化Javascript中的承诺

时间:2014-07-29 11:51:18

标签: javascript angularjs promise angular-promise

以下代码段是否等效?

版本1

function doSomething() {
  var defer = $q.defer();

  foo().then(function() {
    bar().then(function() {
      defer.resolve();
    });
  });

  return defer.promise;
}

版本2

function doSomething() {
  return foo().then(bar);
}

1 个答案:

答案 0 :(得分:6)

这两种方法有很多不同之处。

两个代码段之间的主要区别在于version 2您的foo隐式将已解析的值直接传递给bar。 除此之外,doSomething将解析bar将要解析的内容,而在version 1中,结果将被丢弃。

Benjamin Gruenbaum提出的一些重要观点:

  

(a)如果bar是引用错误1,则拒绝内部承诺和2   抛出。
  (b)1要求提及$ q,其中2是实施   不可知。
  (c)版本1不是例外安全,拒绝将被拒绝   吞噬了版本2会让你。拒绝。 ;有   几个较小的差异也是如此。看到   stackoverflow.com/questions/22539815

你也可以这样写。
这样,您就无法获得从foobar的解析值的隐式传递槽(现在它是显式的),这可能会令人困惑或容易被忽视。如果您想在返回之前对foobar的已解析值执行某些操作,那么它也很有用。

function doSomething() {
  return foo().then(function(res){
     // maybe  do something with the result of foo
     return bar(res);
  }).then(function(res){
     // maybe do something with the result of bar
     return res;
  });
}

手动创建延迟对象应该保持在最低限度,并且通常是反模式。

https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern

这里展示的关键原则是承诺将在其解决方法中采用返回的承诺(或者说是否)的状态。