Angular:$q.defer() 对比 $q()
Angular: $q.defer() vs $q()
在 Angular 中,以下片段似乎是等效的:
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');
}
});
我的问题:如果它们不等价,它们有何不同?如果它们是等价的,是否有令人信服的理由选择一个而不是另一个?
您发布的第二个版本是遵循 Promise/A+-规范的版本。
从功能的角度来看,这两个版本是等效的。第一个版本(在我看来)使异步代码更容易被阅读为同步代码,但第二个版本使用已成为 ES2015 的语法并且也将成为 ES6 的一部分,即下一个版本的javascript.
因此,选择取决于您,但您可以期待在未来看到更多第二种类型的 promise 语法。
就 $q
承诺而言,两者在行为上没有太大差异。第二种方法的主要好处是它使用与原生 promises 相同的样式,并且它很好地包含了解析 promise 的逻辑,而不是有一个松散的延迟悬而未决(这可能是原生 promises 与后一种风格)。
我错误地说过,第二种方法将捕获传入函数中的同步错误并将其转换为拒绝的承诺。这对于原生 promises、Q promises、Bluebird promises 以及其他可能的 promise 都是如此,但对于 $q()
则不然。 $q
只会将错误视为未捕获的错误并将其记录到控制台。
这是一个使用 Bluebird 承诺的示例,说明了我所描述的内容。如果您使用 $q
:
以外的承诺,这是使用后一种风格的一个很好的理由
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 的工作方式一致。
功能是等效的 - 它更多关于 "style"。
一种语法更像 Kris Kowals Q,它是 javascript 中 promises 的第一个实现之一。
其他语法更像是我们将收到的 ES6 实现。
所以使用,你更习惯的 - 如果你开始学习,我建议使用 ES6 方式,因为这将是 "standard javascript" 而不仅仅是 angular 的未来。
有关此主题和您的问题的更多信息,您可以直接在 Angualar 文档中找到:
https://docs.angularjs.org/api/ng/service/$q/
在 Angular 中,以下片段似乎是等效的:
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');
}
});
我的问题:如果它们不等价,它们有何不同?如果它们是等价的,是否有令人信服的理由选择一个而不是另一个?
您发布的第二个版本是遵循 Promise/A+-规范的版本。
从功能的角度来看,这两个版本是等效的。第一个版本(在我看来)使异步代码更容易被阅读为同步代码,但第二个版本使用已成为 ES2015 的语法并且也将成为 ES6 的一部分,即下一个版本的javascript.
因此,选择取决于您,但您可以期待在未来看到更多第二种类型的 promise 语法。
就 $q
承诺而言,两者在行为上没有太大差异。第二种方法的主要好处是它使用与原生 promises 相同的样式,并且它很好地包含了解析 promise 的逻辑,而不是有一个松散的延迟悬而未决(这可能是原生 promises 与后一种风格)。
我错误地说过,第二种方法将捕获传入函数中的同步错误并将其转换为拒绝的承诺。这对于原生 promises、Q promises、Bluebird promises 以及其他可能的 promise 都是如此,但对于 $q()
则不然。 $q
只会将错误视为未捕获的错误并将其记录到控制台。
这是一个使用 Bluebird 承诺的示例,说明了我所描述的内容。如果您使用 $q
:
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 的工作方式一致。
功能是等效的 - 它更多关于 "style"。
一种语法更像 Kris Kowals Q,它是 javascript 中 promises 的第一个实现之一。
其他语法更像是我们将收到的 ES6 实现。
所以使用,你更习惯的 - 如果你开始学习,我建议使用 ES6 方式,因为这将是 "standard javascript" 而不仅仅是 angular 的未来。
有关此主题和您的问题的更多信息,您可以直接在 Angualar 文档中找到: https://docs.angularjs.org/api/ng/service/$q/