【问题标题】:Angular: $q.defer() vs $q() [duplicate]角度:$q.defer() 与 $q() [重复]
【发布时间】:2017-12-10 04:45:31
【问题描述】:

在 Angular 中,以下 sn-ps 似乎是等效的:

let deferred = $q.defer();
if(whatever) {
   deferred.resolve('something');
}
else {
   deferred.reject('nah');
}
return deferred.promise;

return $q((resolve,reject) => {
    if(whatever) {
       resolve('something');
    }
    else {
       reject('nah');
    }
});

我的问题:如果它们不相等,它们有何不同?如果它们是等效的,是否有令人信服的理由偏爱其中一个?

【问题讨论】:

标签: javascript angularjs q angular-promise


【解决方案1】:

您发布的第二个版本是遵循Promise/A+-规范的版本。

从功能的角度来看,两个版本是等效的。第一个版本(在我看来)使将异步代码作为同步代码更容易阅读,但第二个版本使用已使其成为 ES2015 的语法,并且也将成为 ES6 的一部分,即下一个版本的 javascript。

因此,选择权取决于您,但您可以期待在未来看到更多第二种类型的 promise-syntax。

【讨论】:

  • 不,Promise/A+ 没有指定如何构造 Promise。可以使用 deferred 和带有 executor 的构造函数。
【解决方案2】:

$q 的承诺而言,一个与另一个之间没有巨大的行为差异。第二种方法的主要好处是它使用与原生 Promise 相同的样式,并且它很好地包含了解决 Promise 的逻辑,而不是有一个松散的延迟悬空(这可能是原生 Promise 与后一种风格)。

我错误地说过第二种方法会在传入的函数中捕获同步错误并将它们转换为被拒绝的承诺。对于原生承诺、Q 承诺、Bluebird 承诺以及可能的其他承诺都是如此,但对于 $q() 则不是这样。 $q 只会将错误视为未捕获的错误并将其记录到控制台。

这是我所描述的使用 Bluebird Promise 的示例。如果您使用$q 以外的promise,那么使用后一种样式是一个很好的理由:

function queryValue(callback) {
  throw new Error("Not implemented yet!!!");
}

function makeConstructorPromise() {
  return new Promise(function(resolve) {
    queryValue(function(value) {
      resolve(value);
    });
  });
}

function makeDeferredPromise() {
  let deferred = Promise.defer();

  queryValue(function(value) {
    deferred.resolve(value);
  });

  return deferred.promise;
}

makeConstructorPromise()
  .catch(function(error) {
    console.error('caught the constructed promise error!', error);
  });

makeDeferredPromise()
  .catch(function(error) {
    // not caught
    console.error('caught the deferred promise error!', error);
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.5.1/bluebird.min.js"></script>

延迟方法是老式的,可能在非常具体的情况下有实际应用,但 99% 的时间,构造方法是要走的路。

它更安全(在大多数 Promise 实现中)并且与 ES6 Promise 的工作方式一致。

【讨论】:

  • 奇怪,文档说相反:docs.angularjs.org/api/ng/service/$q - “注意:与 ES6 行为不同,构造函数中抛出的异常不会隐式拒绝承诺。”
  • @Marnes Yikes,你是对的。我想我刚刚假设$q 函数像 ES6、Bluebird 和 Q 中的 Promise 构造函数一样工作,但事实并非如此。我会在几个小时内更正我的答案。
  • 嘿伙计,别忘了像你说的那样编辑你的答案。
  • @Marnes 更新了它。抱歉耽搁了。
【解决方案3】:

功能是等价的——更多的是关于“风格”。

一种语法更像 Kris Kowals Q,它是 javascript 中承诺的首批实现之一。

另一种语法更像是我们将在 ES6 中收到的实现。

所以使用你更喜欢的方式 - 如果你开始学习,我建议使用 ES6 方式,因为这将是“标准 javascript”的未来,而不仅仅是 angular。

有关此主题和您的问题的更多信息,您可以直接在 Angular Docu 中找到: https://docs.angularjs.org/api/ng/service/$q/

【讨论】:

    猜你喜欢
    • 2015-09-10
    • 1970-01-01
    • 1970-01-01
    • 2015-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    相关资源
    最近更新 更多